File ovmf-bsc1186151-fix-iscsi-overflows.patch of Package ovmf.28635

From 4bf343fe11b54d36fdaa7596450ef06e0847a30a Mon Sep 17 00:00:00 2001
From: Sean Brogan <sean.brogan@microsoft.com>
Date: Mon, 24 Apr 2017 16:37:20 -0700
Subject: [PATCH 01/18] MdePkg/BaseSafeIntLib: Add SafeIntLib class and
 instance

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

SafeIntLib provides helper functions to prevent integer overflow
during type conversion, addition, subtraction, and multiplication.

Conversion Functions
====================
* Converting from a signed type to an unsigned type of the same
  size, or vice-versa.
* Converting to a smaller type that could possibly overflow.
* Converting from a signed type to a larger unsigned type.

Unsigned Addition, Subtraction, Multiplication
===============================================
* Unsigned integer math functions protect from overflow and
  underflow (in case of subtraction).

Signed Addition, Subtraction, Multiplication
============================================
* Strongly consider using unsigned numbers.
* Signed numbers are often used where unsigned numbers should
  be used. For example file sizes and array indices should always
  be unsigned. Subtracting a larger positive signed number from a
  smaller positive signed number with SafeInt32Sub() will succeed,
  producing a negative number, that then must not be used as an
  array index (but can occasionally be used as a pointer index.)
  Similarly for adding a larger magnitude negative number to a
  smaller magnitude positive number.
* SafeIntLib does not protect you from such errors. It tells you
  if your integer operations overflowed, not if you are doing the
  right thing with your non-overflowed integers.
* Likewise you can overflow a buffer with a non-overflowed
  unsigned index.

Based on content from the following branch/commits:
https://github.com/Microsoft/MS_UEFI/tree/share/MsCapsuleSupport
https://github.com/Microsoft/MS_UEFI/commit/21ef3a321c907b40fa93797619c9f6c686dd92e0
https://github.com/Microsoft/MS_UEFI/commit/ca516b1a61315c2d823f453e12d2135098f53d61
https://github.com/Microsoft/MS_UEFI/commit/33bab4031a417d7d5a7d356c15a14c2e60302b2d

Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Sean Brogan <sean.brogan@microsoft.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
(cherry picked from commit d7a09cb86a0416c099fa3a9e0fbe2c8f399b28de)
---
 MdePkg/Include/AArch64/ProcessorBind.h        |    7 +-
 MdePkg/Include/Arm/ProcessorBind.h            |    7 +-
 MdePkg/Include/Base.h                         |    8 +
 MdePkg/Include/Ebc/ProcessorBind.h            |   17 +-
 MdePkg/Include/Ia32/ProcessorBind.h           |    5 +
 MdePkg/Include/Ipf/ProcessorBind.h            |    7 +-
 MdePkg/Include/Library/SafeIntLib.h           | 3030 ++++++++++++
 MdePkg/Include/X64/ProcessorBind.h            |    5 +
 .../Library/BaseSafeIntLib/BaseSafeIntLib.inf |   58 +
 MdePkg/Library/BaseSafeIntLib/SafeIntLib.c    | 4098 +++++++++++++++++
 MdePkg/Library/BaseSafeIntLib/SafeIntLib32.c  |  554 +++
 MdePkg/Library/BaseSafeIntLib/SafeIntLib64.c  |  508 ++
 MdePkg/Library/BaseSafeIntLib/SafeIntLibEbc.c |  614 +++
 MdePkg/MdePkg.dec                             |    5 +
 MdePkg/MdePkg.dsc                             |    1 +
 15 files changed, 8915 insertions(+), 9 deletions(-)
 create mode 100644 MdePkg/Include/Library/SafeIntLib.h
 create mode 100644 MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
 create mode 100644 MdePkg/Library/BaseSafeIntLib/SafeIntLib.c
 create mode 100644 MdePkg/Library/BaseSafeIntLib/SafeIntLib32.c
 create mode 100644 MdePkg/Library/BaseSafeIntLib/SafeIntLib64.c
 create mode 100644 MdePkg/Library/BaseSafeIntLib/SafeIntLibEbc.c

diff --git a/MdePkg/Include/AArch64/ProcessorBind.h b/MdePkg/Include/AArch64/ProcessorBind.h
index 775e7498c5c9..d9caee598eaa 100644
--- a/MdePkg/Include/AArch64/ProcessorBind.h
+++ b/MdePkg/Include/AArch64/ProcessorBind.h
@@ -1,7 +1,7 @@
 /** @file
   Processor or Compiler specific defines and types for AArch64.
 
-  Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
   Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
   Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
 
@@ -99,6 +99,11 @@ typedef INT64   INTN;
 #define MAX_INTN   ((INTN)0x7FFFFFFFFFFFFFFFULL)
 #define MAX_UINTN  ((UINTN)0xFFFFFFFFFFFFFFFFULL)
 
+///
+/// Minimum legal AArch64 INTN value.
+///
+#define MIN_INTN   (((INTN)-9223372036854775807LL) - 1)
+
 ///
 /// The stack alignment required for AARCH64
 ///
diff --git a/MdePkg/Include/Arm/ProcessorBind.h b/MdePkg/Include/Arm/ProcessorBind.h
index dde1fd1152ba..a0c16491ecde 100644
--- a/MdePkg/Include/Arm/ProcessorBind.h
+++ b/MdePkg/Include/Arm/ProcessorBind.h
@@ -1,7 +1,7 @@
 /** @file
   Processor or Compiler specific defines and types for ARM.
 
-  Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
   Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
   This program and the accompanying materials                          
   are licensed and made available under the terms and conditions of the BSD License         
@@ -105,6 +105,11 @@ typedef INT32   INTN;
 #define MAX_INTN   ((INTN)0x7FFFFFFF)
 #define MAX_UINTN  ((UINTN)0xFFFFFFFF)
 
+///
+/// Minimum legal ARM INTN value.
+///
+#define MIN_INTN   (((INTN)-2147483647) - 1)
+
 ///
 /// The stack alignment required for ARM
 ///
diff --git a/MdePkg/Include/Base.h b/MdePkg/Include/Base.h
index 52252e7dc500..1efa78485e24 100644
--- a/MdePkg/Include/Base.h
+++ b/MdePkg/Include/Base.h
@@ -376,6 +376,14 @@ struct _LIST_ENTRY {
 #define MAX_INT64   ((INT64)0x7FFFFFFFFFFFFFFFULL)
 #define MAX_UINT64  ((UINT64)0xFFFFFFFFFFFFFFFFULL)
 
+///
+/// Minimum values for the signed UEFI Data Types
+///
+#define MIN_INT8   (((INT8)  -127) - 1)
+#define MIN_INT16  (((INT16) -32767) - 1)
+#define MIN_INT32  (((INT32) -2147483647) - 1)
+#define MIN_INT64  (((INT64) -9223372036854775807LL) - 1)
+
 #define  BIT0     0x00000001
 #define  BIT1     0x00000002
 #define  BIT2     0x00000004
diff --git a/MdePkg/Include/Ebc/ProcessorBind.h b/MdePkg/Include/Ebc/ProcessorBind.h
index da8b1a6d802a..ed4164891328 100644
--- a/MdePkg/Include/Ebc/ProcessorBind.h
+++ b/MdePkg/Include/Ebc/ProcessorBind.h
@@ -4,7 +4,7 @@
   We currently only have one EBC compiler so there may be some Intel compiler
   specific functions in this file.
 
-Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials are licensed and made available under 
 the terms and conditions of the BSD License that accompanies this distribution.  
 The full text of the license may be found at
@@ -91,23 +91,28 @@ typedef unsigned long         UINTN;
 /// A value of native width with the highest bit set.
 /// Scalable macro to set the most significant bit in a natural number.
 ///
-#define MAX_BIT     (1ULL << (sizeof (INTN) * 8 - 1)) 
+#define MAX_BIT     ((UINTN)((1ULL << (sizeof (INTN) * 8 - 1))))
 ///
 /// A value of native width with the two highest bits set.
 /// Scalable macro to set the most 2 significant bits in a natural number.
 ///
-#define MAX_2_BITS  (3ULL << (sizeof (INTN) * 8 - 2))
+#define MAX_2_BITS  ((UINTN)(3ULL << (sizeof (INTN) * 8 - 2)))
 
 ///
 /// Maximum legal EBC address
 ///
-#define MAX_ADDRESS   ((UINTN) ~0)
+#define MAX_ADDRESS   ((UINTN)(~0ULL >> (64 - sizeof (INTN) * 8)))
 
 ///
 /// Maximum legal EBC INTN and UINTN values.
 ///
-#define MAX_UINTN  ((UINTN) ~0)
-#define MAX_INTN   ((INTN)~MAX_BIT)
+#define MAX_UINTN  ((UINTN)(~0ULL >> (64 - sizeof (INTN) * 8)))
+#define MAX_INTN   ((INTN)(~0ULL >> (65 - sizeof (INTN) * 8)))
+
+///
+/// Minimum legal EBC INTN value.
+///
+#define MIN_INTN   (((INTN)-MAX_INTN) - 1)
 
 ///
 /// The stack alignment required for EBC
diff --git a/MdePkg/Include/Ia32/ProcessorBind.h b/MdePkg/Include/Ia32/ProcessorBind.h
index 8ba2348261a2..6b723eba3de0 100644
--- a/MdePkg/Include/Ia32/ProcessorBind.h
+++ b/MdePkg/Include/Ia32/ProcessorBind.h
@@ -252,6 +252,11 @@ typedef INT32   INTN;
 #define MAX_INTN   ((INTN)0x7FFFFFFF)
 #define MAX_UINTN  ((UINTN)0xFFFFFFFF)
 
+///
+/// Minimum legal IA-32 INTN value.
+///
+#define MIN_INTN   (((INTN)-2147483647) - 1)
+
 ///
 /// The stack alignment required for IA-32.
 ///
diff --git a/MdePkg/Include/Ipf/ProcessorBind.h b/MdePkg/Include/Ipf/ProcessorBind.h
index 51885ca61359..bfbae01abb84 100644
--- a/MdePkg/Include/Ipf/ProcessorBind.h
+++ b/MdePkg/Include/Ipf/ProcessorBind.h
@@ -1,7 +1,7 @@
 /** @file
   Processor or Compiler specific defines and types for Intel Itanium(TM) processors.
 
-Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials are licensed and made available 
 under the terms and conditions of the BSD License which accompanies this
 distribution.  The full text of the license may be found at
@@ -242,6 +242,11 @@ typedef INT64   INTN;
 #define MAX_INTN   ((INTN)0x7FFFFFFFFFFFFFFFULL)
 #define MAX_UINTN  ((UINTN)0xFFFFFFFFFFFFFFFFULL)
 
+///
+/// Minimum legal Itanium-based INTN value.
+///
+#define MIN_INTN   (((INTN)-9223372036854775807LL) - 1)
+
 ///
 /// Per the Itanium Software Conventions and Runtime Architecture Guide,
 /// section 3.3.4, IPF stack must always be 16-byte aligned.
diff --git a/MdePkg/Include/Library/SafeIntLib.h b/MdePkg/Include/Library/SafeIntLib.h
new file mode 100644
index 000000000000..583930195a61
--- /dev/null
+++ b/MdePkg/Include/Library/SafeIntLib.h
@@ -0,0 +1,3030 @@
+/** @file
+  This library provides helper functions to prevent integer overflow during
+  type conversion, addition, subtraction, and multiplication.
+
+  Copyright (c) 2017, Microsoft Corporation
+
+  All rights reserved.
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+  1. Redistributions of source code must retain the above copyright notice,
+  this list of conditions and the following disclaimer.
+  2. Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+**/
+#ifndef __INT_SAFE_LIB_H__
+#define __INT_SAFE_LIB_H__
+
+//
+// It is common for -1 to be used as an error value
+//
+#define INT8_ERROR    ((INT8) -1)
+#define UINT8_ERROR   MAX_UINT8
+#define CHAR8_ERROR   ((CHAR8)(MAX_INT8))
+#define INT16_ERROR   ((INT16) -1)
+#define UINT16_ERROR  MAX_UINT16
+#define CHAR16_ERROR  MAX_UINT16
+#define INT32_ERROR   ((INT32) -1)
+#define UINT32_ERROR  MAX_UINT32
+#define INT64_ERROR   ((INT64) -1)
+#define UINT64_ERROR  MAX_UINT64
+#define INTN_ERROR    ((INTN) -1)
+#define UINTN_ERROR   MAX_UINTN
+
+//
+// CHAR16 is defined to be the same as UINT16, so for CHAR16
+// operations redirect to the UINT16 ones:
+//
+#define SafeInt8ToChar16    SafeInt8ToUint16
+#define SafeInt16ToChar16   SafeInt16ToUint16
+#define SafeInt32ToChar16   SafeInt32ToUint16
+#define SafeUint32ToChar16  SafeUint32ToUint16
+#define SafeInt64ToChar16   SafeInt64ToUint16
+#define SafeUint64ToChar16  SafeUint64ToUint16
+#define SafeIntnToChar16    SafeIntnToUint16
+#define SafeUintnToChar16   SafeUintnToUint16
+
+#define SafeChar16ToInt8    SafeUint16ToInt8
+#define SafeChar16ToUint8   SafeUint16ToUint8
+#define SafeChar16ToChar8   SafeUint16ToChar8
+#define SafeChar16ToInt16   SafeUint16ToInt16
+
+#define SafeChar16Mult      SafeUint16Mult
+#define SafeChar16Sub       SafeUint16Sub
+#define SafeChar16Add       SafeUint16Add
+
+//
+// Conversion functions
+//
+// There are three reasons for having conversion functions:
+//
+// 1. We are converting from a signed type to an unsigned type of the same
+//    size, or vice-versa.
+//
+// 2. We are converting to a smaller type, and we could therefore possibly
+//    overflow.
+//
+// 3. We are converting to a bigger type, and we are signed and the type we are
+//    converting to is unsigned.
+//
+
+/**
+  INT8 -> UINT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt8ToUint8 (
+  IN  INT8   Operand,
+  OUT UINT8  *Result
+  );
+
+/**
+  INT8 -> CHAR8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt8ToChar8 (
+  IN  INT8   Operand,
+  OUT CHAR8  *Result
+  );
+
+/**
+  INT8 -> UINT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt8ToUint16 (
+  IN  INT8    Operand,
+  OUT UINT16  *Result
+  );
+
+/**
+  INT8 -> UINT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt8ToUint32 (
+  IN  INT8    Operand,
+  OUT UINT32  *Result
+  );
+
+/**
+  INT8 -> UINTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt8ToUintn (
+  IN  INT8   Operand,
+  OUT UINTN  *Result
+  );
+
+/**
+  INT8 -> UINT64 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt8ToUint64 (
+  IN  INT8    Operand,
+  OUT UINT64  *Result
+  );
+
+/**
+  UINT8 -> INT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint8ToInt8 (
+  IN  UINT8  Operand,
+  OUT INT8   *Result
+  );
+
+/**
+  UINT8 -> CHAR8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint8ToChar8 (
+  IN  UINT8  Operand,
+  OUT CHAR8  *Result
+  );
+
+/**
+  INT16 -> INT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt16ToInt8 (
+  IN  INT16  Operand,
+  OUT INT8   *Result
+  );
+
+/**
+  INT16 -> CHAR8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt16ToChar8 (
+  IN  INT16  Operand,
+  OUT CHAR8  *Result
+  );
+
+/**
+  INT16 -> UINT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt16ToUint8 (
+  IN INT16 Operand,
+  OUT UINT8 *pui8Result
+  );
+
+/**
+  INT16 -> UINT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt16ToUint16 (
+  IN  INT16   Operand,
+  OUT UINT16  *Result
+  );
+
+/**
+  INT16 -> UINT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt16ToUint32 (
+  IN  INT16   Operand,
+  OUT UINT32  *Result
+  );
+
+/**
+  INT16 -> UINTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt16ToUintn (
+  IN  INT16  Operand,
+  OUT UINTN  *Result
+  );
+
+/**
+  INT16 -> UINT64 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt16ToUint64 (
+  IN  INT16   Operand,
+  OUT UINT64  *Result
+  );
+
+/**
+  UINT16 -> INT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint16ToInt8 (
+  IN  UINT16  Operand,
+  OUT INT8    *Result
+  );
+
+/**
+  UINT16 -> CHAR8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint16ToChar8 (
+  IN  UINT16  Operand,
+  OUT CHAR8   *Result
+  );
+
+/**
+  UINT16 -> UINT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint16ToUint8 (
+  IN UINT16 Operand,
+  OUT UINT8 *pui8Result
+  );
+
+/**
+  UINT16 -> INT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint16ToInt16 (
+  IN  UINT16  Operand,
+  OUT INT16   *Result
+  );
+
+/**
+  INT32 -> INT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32ToInt8 (
+  IN  INT32  Operand,
+  OUT INT8   *Result
+  );
+
+/**
+  INT32 -> CHAR8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32ToChar8 (
+  IN  INT32  Operand,
+  OUT CHAR8  *Result
+  );
+
+/**
+  INT32 -> UINT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32ToUint8 (
+  IN INT32 Operand,
+  OUT UINT8 *pui8Result
+  );
+
+/**
+  INT32 -> INT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32ToInt16 (
+  IN  INT32  Operand,
+  OUT INT16  *Result
+  );
+
+/**
+  INT32 -> UINT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32ToUint16 (
+  IN  INT32   Operand,
+  OUT UINT16  *Result
+  );
+
+
+/**
+  INT32 -> UINT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32ToUint32 (
+  IN  INT32   Operand,
+  OUT UINT32  *Result
+  );
+
+/**
+  INT32 -> UINTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32ToUintn (
+  IN  INT32  Operand,
+  OUT UINTN  *Result
+  );
+
+/**
+  INT32 -> UINT64 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32ToUint64 (
+  IN  INT32   Operand,
+  OUT UINT64  *Result
+  );
+
+/**
+  UINT32 -> INT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint32ToInt8 (
+  IN  UINT32  Operand,
+  OUT INT8    *Result
+  );
+
+/**
+  UINT32 -> CHAR8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint32ToChar8 (
+  IN  UINT32  Operand,
+  OUT CHAR8   *Result
+  );
+
+/**
+  UINT32 -> UINT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint32ToUint8 (
+  IN UINT32 Operand,
+  OUT UINT8 *pui8Result
+  );
+
+/**
+  UINT32 -> INT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint32ToInt16 (
+  IN  UINT32  Operand,
+  OUT INT16   *Result
+  );
+
+/**
+  UINT32 -> UINT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint32ToUint16 (
+  IN  UINT32  Operand,
+  OUT UINT16  *Result
+  );
+
+/**
+  UINT32 -> INT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint32ToInt32 (
+  IN  UINT32  Operand,
+  OUT INT32   *Result
+  );
+
+/**
+  UINT32 -> INTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint32ToIntn (
+  IN  UINT32  Operand,
+  OUT INTN    *Result
+  );
+
+/**
+  INTN -> INT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnToInt8 (
+  IN  INTN  Operand,
+  OUT INT8  *Result
+  );
+
+/**
+  INTN -> CHAR8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnToChar8 (
+  IN  INTN   Operand,
+  OUT CHAR8  *Result
+  );
+
+/**
+  INTN -> UINT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnToUint8 (
+  IN INTN Operand,
+  OUT UINT8 *pui8Result
+  );
+
+/**
+  INTN -> INT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnToInt16 (
+  IN  INTN   Operand,
+  OUT INT16  *Result
+  );
+
+/**
+  INTN -> UINT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnToUint16 (
+  IN  INTN    Operand,
+  OUT UINT16  *Result
+  );
+
+/**
+  INTN -> INT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnToInt32 (
+  IN  INTN   Operand,
+  OUT INT32  *Result
+  );
+
+/**
+  INTN -> UINT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnToUint32 (
+  IN  INTN    Operand,
+  OUT UINT32  *Result
+  );
+
+/**
+  INTN -> UINTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnToUintn (
+  IN  INTN   Operand,
+  OUT UINTN  *Result
+  );
+
+/**
+  INTN -> UINT64 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnToUint64 (
+  IN  INTN    Operand,
+  OUT UINT64  *Result
+  );
+
+/**
+  UINTN -> INT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnToInt8 (
+  IN  UINTN  Operand,
+  OUT INT8   *Result
+  );
+
+/**
+  UINTN -> CHAR8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnToChar8 (
+  IN  UINTN  Operand,
+  OUT CHAR8  *Result
+  );
+
+/**
+  UINTN -> UINT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnToUint8 (
+  IN UINTN Operand,
+  OUT UINT8 *pui8Result
+  );
+
+/**
+  UINTN -> INT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnToInt16 (
+  IN  UINTN  Operand,
+  OUT INT16  *Result
+  );
+
+/**
+  UINTN -> UINT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnToUint16 (
+  IN  UINTN   Operand,
+  OUT UINT16  *Result
+  );
+
+/**
+  UINTN -> INT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnToInt32 (
+  IN  UINTN  Operand,
+  OUT INT32  *Result
+  );
+
+/**
+  UINTN -> UINT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnToUint32 (
+  IN  UINTN   Operand,
+  OUT UINT32  *Result
+  );
+
+/**
+  UINTN -> INTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnToIntn (
+  IN  UINTN  Operand,
+  OUT INTN   *Result
+  );
+
+/**
+  UINTN -> INT64 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnToInt64 (
+  IN  UINTN  Operand,
+  OUT INT64  *Result
+  );
+
+/**
+  INT64 -> INT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToInt8 (
+  IN  INT64  Operand,
+  OUT INT8   *Result
+  );
+
+/**
+  INT64 -> CHAR8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToChar8 (
+  IN  INT64  Operand,
+  OUT CHAR8  *Result
+  );
+
+/**
+  INT64 -> UINT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToUint8 (
+  IN  INT64  Operand,
+  OUT UINT8  *Result
+  );
+
+/**
+  INT64 -> INT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToInt16 (
+  IN  INT64  Operand,
+  OUT INT16  *Result
+  );
+
+/**
+  INT64 -> UINT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToUint16 (
+  IN  INT64   Operand,
+  OUT UINT16  *Result
+  );
+
+/**
+  INT64 -> INT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToInt32 (
+  IN  INT64  Operand,
+  OUT INT32  *Result
+  );
+
+/**
+  INT64 -> UINT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToUint32 (
+  IN  INT64   Operand,
+  OUT UINT32  *Result
+  );
+
+/**
+  INT64 -> INTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToIntn (
+  IN  INT64  Operand,
+  OUT INTN   *Result
+  );
+
+/**
+  INT64 -> UINTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToUintn (
+  IN  INT64  Operand,
+  OUT UINTN  *Result
+  );
+
+/**
+  INT64 -> UINT64 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToUint64 (
+  IN  INT64   Operand,
+  OUT UINT64  *Result
+  );
+
+/**
+  UINT64 -> INT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64ToInt8 (
+  IN  UINT64  Operand,
+  OUT INT8    *Result
+  );
+
+/**
+  UINT64 -> CHAR8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64ToChar8 (
+  IN  UINT64  Operand,
+  OUT CHAR8   *Result
+  );
+
+/**
+  UINT64 -> UINT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64ToUint8 (
+  IN  UINT64  Operand,
+  OUT UINT8   *Result
+  );
+
+/**
+  UINT64 -> INT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64ToInt16 (
+  IN  UINT64  Operand,
+  OUT INT16   *Result
+  );
+
+/**
+  UINT64 -> UINT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64ToUint16 (
+  IN  UINT64  Operand,
+  OUT UINT16  *Result
+  );
+
+/**
+  UINT64 -> INT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64ToInt32 (
+  IN  UINT64  Operand,
+  OUT INT32   *Result
+  );
+
+/**
+  UINT64 -> UINT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64ToUint32 (
+  IN  UINT64  Operand,
+  OUT UINT32  *Result
+  );
+
+/**
+  UINT64 -> INTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64ToIntn (
+  IN  UINT64  Operand,
+  OUT INTN    *Result
+  );
+
+/**
+  UINT64 -> UINTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64ToUintn (
+  IN  UINT64  Operand,
+  OUT UINTN   *Result
+  );
+
+/**
+  UINT64 -> INT64 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64ToInt64 (
+  IN  UINT64  Operand,
+  OUT INT64   *Result
+  );
+
+//
+// Addition functions
+//
+
+/**
+  UINT8 addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint8Add (
+  IN  UINT8  Augend,
+  IN  UINT8  Addend,
+  OUT UINT8  *Result
+  );
+
+/**
+  UINT16 addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint16Add (
+  IN  UINT16  Augend,
+  IN  UINT16  Addend,
+  OUT UINT16  *Result
+  );
+
+/**
+  UINT32 addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint32Add (
+  IN  UINT32  Augend,
+  IN  UINT32  Addend,
+  OUT UINT32  *Result
+  );
+
+/**
+  UINTN addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnAdd (
+  IN  UINTN  Augend,
+  IN  UINTN  Addend,
+  OUT UINTN  *Result
+  );
+
+/**
+  UINT64 addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64Add (
+  IN  UINT64  Augend,
+  IN  UINT64  Addend,
+  OUT UINT64  *Result
+  );
+
+//
+// Subtraction functions
+//
+
+/**
+  UINT8 subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint8Sub (
+  IN  UINT8  Minuend,
+  IN  UINT8  Subtrahend,
+  OUT UINT8  *Result
+  );
+
+/**
+  UINT16 subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint16Sub (
+  IN  UINT16  Minuend,
+  IN  UINT16  Subtrahend,
+  OUT UINT16  *Result
+  );
+
+/**
+  UINT32 subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint32Sub (
+  IN  UINT32  Minuend,
+  IN  UINT32  Subtrahend,
+  OUT UINT32  *Result
+  );
+
+/**
+  UINTN subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnSub (
+  IN  UINTN  Minuend,
+  IN  UINTN  Subtrahend,
+  OUT UINTN  *Result
+  );
+
+/**
+  UINT64 subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64Sub (
+  IN  UINT64  Minuend,
+  IN  UINT64  Subtrahend,
+  OUT UINT64  *Result
+  );
+
+//
+// Multiplication functions
+//
+
+/**
+  UINT8 multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint8Mult (
+  IN  UINT8  Multiplicand,
+  IN  UINT8  Multiplier,
+  OUT UINT8  *Result
+  );
+
+/**
+  UINT16 multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint16Mult (
+  IN  UINT16  Multiplicand,
+  IN  UINT16  Multiplier,
+  OUT UINT16  *Result
+  );
+
+/**
+  UINT32 multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint32Mult (
+  IN  UINT32  Multiplicand,
+  IN  UINT32  Multiplier,
+  OUT UINT32  *Result
+  );
+
+/**
+  UINTN multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnMult (
+  IN  UINTN  Multiplicand,
+  IN  UINTN  Multiplier,
+  OUT UINTN  *Result
+  );
+
+/**
+  UINT64 multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64Mult (
+  IN  UINT64  Multiplicand,
+  IN  UINT64  Multiplier,
+  OUT UINT64  *Result
+  );
+
+//
+// Signed operations
+//
+// Strongly consider using unsigned numbers.
+//
+// Signed numbers are often used where unsigned numbers should be used.
+// For example file sizes and array indices should always be unsigned.
+// Subtracting a larger positive signed number from a smaller positive
+// signed number with SafeInt32Sub will succeed, producing a negative number,
+// that then must not be used as an array index (but can occasionally be
+// used as a pointer index.) Similarly for adding a larger magnitude
+// negative number to a smaller magnitude positive number.
+//
+// This library does not protect you from such errors. It tells you if your
+// integer operations overflowed, not if you are doing the right thing
+// with your non-overflowed integers.
+//
+// Likewise you can overflow a buffer with a non-overflowed unsigned index.
+//
+
+//
+// Signed addition functions
+//
+
+/**
+  INT8 Addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt8Add (
+  IN  INT8  Augend,
+  IN  INT8  Addend,
+  OUT INT8  *Result
+  );
+
+/**
+  CHAR8 Addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeChar8Add (
+  IN  CHAR8  Augend,
+  IN  CHAR8  Addend,
+  OUT CHAR8  *Result
+  );
+
+/**
+  INT16 Addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt16Add (
+  IN  INT16  Augend,
+  IN  INT16  Addend,
+  OUT INT16  *Result
+  );
+
+/**
+  INT32 Addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32Add (
+  IN  INT32  Augend,
+  IN  INT32  Addend,
+  OUT INT32  *Result
+  );
+
+/**
+  INTN Addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnAdd (
+  IN  INTN  Augend,
+  IN  INTN  Addend,
+  OUT INTN  *Result
+  );
+
+/**
+  INT64 Addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64Add (
+  IN  INT64  Augend,
+  IN  INT64  Addend,
+  OUT INT64  *Result
+  );
+
+//
+// Signed subtraction functions
+//
+
+/**
+  INT8 Subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt8Sub (
+  IN  INT8  Minuend,
+  IN  INT8  Subtrahend,
+  OUT INT8  *Result
+  );
+
+/**
+  CHAR8 Subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeChar8Sub (
+  IN  CHAR8  Minuend,
+  IN  CHAR8  Subtrahend,
+  OUT CHAR8  *Result
+  );
+
+/**
+  INT16 Subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt16Sub (
+  IN  INT16  Minuend,
+  IN  INT16  Subtrahend,
+  OUT INT16  *Result
+  );
+
+/**
+  INT32 Subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32Sub (
+  IN  INT32  Minuend,
+  IN  INT32  Subtrahend,
+  OUT INT32  *Result
+  );
+
+/**
+  INTN Subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnSub (
+  IN  INTN  Minuend,
+  IN  INTN  Subtrahend,
+  OUT INTN  *Result
+  );
+
+/**
+  INT64 Subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64Sub (
+  IN  INT64  Minuend,
+  IN  INT64  Subtrahend,
+  OUT INT64  *Result
+  );
+
+//
+// Signed multiplication functions
+//
+
+/**
+  INT8 multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt8Mult (
+  IN  INT8  Multiplicand,
+  IN  INT8  Multiplier,
+  OUT INT8  *Result
+  );
+
+/**
+  CHAR8 multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeChar8Mult (
+  IN  CHAR8  Multiplicand,
+  IN  CHAR8  Multiplier,
+  OUT CHAR8  *Result
+  );
+
+/**
+  INT16 multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt16Mult (
+  IN  INT16  Multiplicand,
+  IN  INT16  Multiplier,
+  OUT INT16  *Result
+  );
+
+/**
+  INT32 multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32Mult (
+  IN  INT32  Multiplicand,
+  IN  INT32  Multiplier,
+  OUT INT32  *Result
+  );
+
+/**
+  INTN multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnMult (
+  IN  INTN  Multiplicand,
+  IN  INTN  Multiplier,
+  OUT INTN  *Result
+  );
+
+/**
+  INT64 multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64Mult (
+  IN  INT64  Multiplicand,
+  IN  INT64  Multiplier,
+  OUT INT64  *Result
+  );
+
+#endif // __INT_SAFE_LIB_H__
diff --git a/MdePkg/Include/X64/ProcessorBind.h b/MdePkg/Include/X64/ProcessorBind.h
index 72cc85151cba..de793b321586 100644
--- a/MdePkg/Include/X64/ProcessorBind.h
+++ b/MdePkg/Include/X64/ProcessorBind.h
@@ -266,6 +266,11 @@ typedef INT64   INTN;
 #define MAX_INTN   ((INTN)0x7FFFFFFFFFFFFFFFULL)
 #define MAX_UINTN  ((UINTN)0xFFFFFFFFFFFFFFFFULL)
 
+///
+/// Minimum legal x64 INTN value.
+///
+#define MIN_INTN   (((INTN)-9223372036854775807LL) - 1)
+
 ///
 /// The stack alignment required for x64
 ///
diff --git a/MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf b/MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
new file mode 100644
index 000000000000..20a83ed97bca
--- /dev/null
+++ b/MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
@@ -0,0 +1,58 @@
+## @file
+# Safe Integer Library
+#
+# This library provides helper functions to prevent integer overflow during
+# type conversion, addition, subtraction, and multiplication.
+#
+# Copyright (c) 2017, Microsoft Corporation
+#
+# All rights reserved.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+#  and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BaseSafeIntLib
+  FILE_GUID                      = 4EA91BFA-3482-4930-B136-70679C6CE489
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SafeIntLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  SafeIntLib.c
+
+[Sources.Ia32, Sources.ARM]
+  SafeIntLib32.c
+
+[Sources.X64, Sources.IPF, Sources.AARCH64]
+  SafeIntLib64.c
+
+[Sources.EBC]
+  SafeIntLibEbc.c
+
+[Packages]
+  MdePkg/MdePkg.dec
diff --git a/MdePkg/Library/BaseSafeIntLib/SafeIntLib.c b/MdePkg/Library/BaseSafeIntLib/SafeIntLib.c
new file mode 100644
index 000000000000..d846160ba0d1
--- /dev/null
+++ b/MdePkg/Library/BaseSafeIntLib/SafeIntLib.c
@@ -0,0 +1,4098 @@
+/** @file
+  This library provides helper functions to prevent integer overflow during
+  type conversion, addition, subtraction, and multiplication.
+
+  Copyright (c) 2017, Microsoft Corporation
+
+  All rights reserved.
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+  1. Redistributions of source code must retain the above copyright notice,
+  this list of conditions and the following disclaimer.
+  2. Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+**/
+
+#include <Base.h>
+#include <Library/SafeIntLib.h>
+
+
+//
+// Magnitude of MIN_INT64 as expressed by a UINT64 number.
+//
+#define MIN_INT64_MAGNITUDE ((((UINT64) - (MIN_INT64 + 1))) + 1)
+
+//
+// Conversion functions
+//
+// There are three reasons for having conversion functions:
+//
+// 1. We are converting from a signed type to an unsigned type of the same
+//    size, or vice-versa.
+//
+// 2. We are converting to a smaller type, and we could therefore possibly
+//    overflow.
+//
+// 3. We are converting to a bigger type, and we are signed and the type we are
+//    converting to is unsigned.
+//
+
+/**
+  INT8 -> UINT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt8ToUint8 (
+  IN  INT8   Operand,
+  OUT UINT8  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand >= 0) {
+    *Result = (UINT8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT8 -> CHAR8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt8ToChar8 (
+  IN  INT8   Operand,
+  OUT CHAR8  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand >= 0) {
+    *Result = (CHAR8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = CHAR8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT8 -> UINT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt8ToUint16 (
+  IN  INT8    Operand,
+  OUT UINT16  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand >= 0) {
+    *Result = (UINT16)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT16_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT8 -> UINT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt8ToUint32 (
+  IN  INT8    Operand,
+  OUT UINT32  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand >= 0) {
+    *Result = (UINT32)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT32_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT8 -> UINTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt8ToUintn (
+  IN  INT8   Operand,
+  OUT UINTN  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand >= 0) {
+    *Result = (UINTN)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINTN_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT8 -> UINT64 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt8ToUint64 (
+  IN  INT8    Operand,
+  OUT UINT64  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand >= 0) {
+    *Result = (UINT64)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT64_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT8 -> INT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint8ToInt8 (
+  IN  UINT8  Operand,
+  OUT INT8   *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_INT8) {
+    *Result = (INT8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INT8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT8 -> CHAR8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint8ToChar8 (
+  IN  UINT8  Operand,
+  OUT CHAR8  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_INT8) {
+    *Result = (CHAR8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = CHAR8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT16 -> INT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt16ToInt8 (
+  IN  INT16  Operand,
+  OUT INT8   *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Operand >= MIN_INT8) && (Operand <= MAX_INT8)) {
+    *Result = (INT8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INT8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT16 -> CHAR8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt16ToChar8 (
+  IN  INT16  Operand,
+  OUT CHAR8  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Operand >= 0) && (Operand <= MAX_INT8)) {
+    *Result = (CHAR8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = CHAR8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT16 -> UINT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt16ToUint8 (
+  IN  INT16  Operand,
+  OUT UINT8  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Operand >= 0) && (Operand <= MAX_UINT8)) {
+    *Result = (UINT8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT16 -> UINT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt16ToUint16 (
+  IN  INT16   Operand,
+  OUT UINT16  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand >= 0) {
+    *Result = (UINT16)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT16_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT16 -> UINT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt16ToUint32 (
+  IN  INT16   Operand,
+  OUT UINT32  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand >= 0) {
+    *Result = (UINT32)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT32_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT16 -> UINTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt16ToUintn (
+  IN  INT16  Operand,
+  OUT UINTN  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand >= 0) {
+    *Result = (UINTN)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINTN_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT16 -> UINT64 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt16ToUint64 (
+  IN  INT16   Operand,
+  OUT UINT64  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand >= 0) {
+    *Result = (UINT64)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT64_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT16 -> INT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint16ToInt8 (
+  IN  UINT16  Operand,
+  OUT INT8    *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_INT8) {
+    *Result = (INT8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INT8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT16 -> CHAR8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint16ToChar8 (
+  IN  UINT16  Operand,
+  OUT CHAR8   *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_INT8) {
+    *Result = (INT8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = CHAR8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT16 -> UINT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint16ToUint8 (
+  IN  UINT16  Operand,
+  OUT UINT8   *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_UINT8) {
+    *Result = (UINT8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT16 -> INT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint16ToInt16 (
+  IN  UINT16  Operand,
+  OUT INT16   *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_INT16) {
+    *Result = (INT16)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INT16_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT32 -> INT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32ToInt8 (
+  IN  INT32  Operand,
+  OUT INT8   *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Operand >= MIN_INT8) && (Operand <= MAX_INT8)) {
+    *Result = (INT8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INT8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT32 -> CHAR8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32ToChar8 (
+  IN  INT32  Operand,
+  OUT CHAR8  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Operand >= 0) && (Operand <= MAX_INT8)) {
+    *Result = (CHAR8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = CHAR8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT32 -> UINT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32ToUint8 (
+  IN  INT32  Operand,
+  OUT UINT8  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Operand >= 0) && (Operand <= MAX_UINT8)) {
+    *Result = (UINT8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT32 -> INT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32ToInt16 (
+  IN  INT32  Operand,
+  OUT INT16  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Operand >= MIN_INT16) && (Operand <= MAX_INT16)) {
+    *Result = (INT16)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INT16_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT32 -> UINT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32ToUint16 (
+  IN  INT32   Operand,
+  OUT UINT16  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Operand >= 0) && (Operand <= MAX_UINT16)) {
+    *Result = (UINT16)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT16_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT32 -> UINT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32ToUint32 (
+  IN  INT32   Operand,
+  OUT UINT32  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand >= 0) {
+    *Result = (UINT32)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT32_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT32 -> UINT64 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32ToUint64 (
+  IN  INT32   Operand,
+  OUT UINT64  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand >= 0) {
+    *Result = (UINT64)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT64_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT32 -> INT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint32ToInt8 (
+  IN  UINT32  Operand,
+  OUT INT8    *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_INT8) {
+    *Result = (INT8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INT8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT32 -> CHAR8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint32ToChar8 (
+  IN  UINT32  Operand,
+  OUT CHAR8   *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_INT8) {
+    *Result = (INT8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = CHAR8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT32 -> UINT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint32ToUint8 (
+  IN  UINT32  Operand,
+  OUT UINT8   *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_UINT8) {
+    *Result = (UINT8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT32 -> INT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint32ToInt16 (
+  IN  UINT32  Operand,
+  OUT INT16   *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_INT16) {
+    *Result = (INT16)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INT16_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT32 -> UINT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint32ToUint16 (
+  IN  UINT32  Operand,
+  OUT UINT16  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_UINT16) {
+    *Result = (UINT16)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT16_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT32 -> INT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint32ToInt32 (
+  IN  UINT32  Operand,
+  OUT INT32   *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_INT32) {
+    *Result = (INT32)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INT32_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INTN -> INT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnToInt8 (
+  IN  INTN  Operand,
+  OUT INT8  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Operand >= MIN_INT8) && (Operand <= MAX_INT8)) {
+    *Result = (INT8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INT8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INTN -> CHAR8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnToChar8 (
+  IN  INTN   Operand,
+  OUT CHAR8  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Operand >= 0) && (Operand <= MAX_INT8)) {
+    *Result = (CHAR8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = CHAR8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INTN -> UINT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnToUint8 (
+  IN  INTN   Operand,
+  OUT UINT8  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Operand >= 0) && (Operand <= MAX_UINT8)) {
+    *Result = (UINT8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INTN -> INT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnToInt16 (
+  IN  INTN   Operand,
+  OUT INT16  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Operand >= MIN_INT16) && (Operand <= MAX_INT16)) {
+    *Result = (INT16)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INT16_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INTN -> UINT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnToUint16 (
+  IN  INTN    Operand,
+  OUT UINT16  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Operand >= 0) && (Operand <= MAX_UINT16)) {
+    *Result = (UINT16)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT16_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INTN -> UINTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnToUintn (
+  IN  INTN   Operand,
+  OUT UINTN  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand >= 0) {
+    *Result = (UINTN)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINTN_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INTN -> UINT64 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnToUint64 (
+  IN  INTN    Operand,
+  OUT UINT64  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand >= 0) {
+    *Result = (UINT64)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT64_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINTN -> INT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnToInt8 (
+  IN  UINTN  Operand,
+  OUT INT8   *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_INT8) {
+    *Result = (INT8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INT8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINTN -> CHAR8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnToChar8 (
+  IN  UINTN  Operand,
+  OUT CHAR8  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_INT8) {
+    *Result = (INT8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = CHAR8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINTN -> UINT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnToUint8 (
+  IN  UINTN  Operand,
+  OUT UINT8  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_UINT8) {
+    *Result = (UINT8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINTN -> INT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnToInt16 (
+  IN  UINTN  Operand,
+  OUT INT16  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_INT16) {
+    *Result = (INT16)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INT16_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINTN -> UINT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnToUint16 (
+  IN  UINTN   Operand,
+  OUT UINT16  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_UINT16) {
+    *Result = (UINT16)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT16_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINTN -> INT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnToInt32 (
+  IN  UINTN  Operand,
+  OUT INT32  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_INT32) {
+    *Result = (INT32)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INT32_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINTN -> INTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnToIntn (
+  IN  UINTN  Operand,
+  OUT INTN   *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_INTN) {
+    *Result = (INTN)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INTN_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT64 -> INT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToInt8 (
+  IN  INT64  Operand,
+  OUT INT8   *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Operand >= MIN_INT8) && (Operand <= MAX_INT8)) {
+    *Result = (INT8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INT8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT64 -> CHAR8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToChar8 (
+  IN  INT64  Operand,
+  OUT CHAR8  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Operand >= 0) && (Operand <= MAX_INT8)) {
+    *Result = (CHAR8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = CHAR8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT64 -> UINT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToUint8 (
+  IN  INT64  Operand,
+  OUT UINT8  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Operand >= 0) && (Operand <= MAX_UINT8)) {
+    *Result = (UINT8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT64 -> INT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToInt16 (
+  IN  INT64  Operand,
+  OUT INT16  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Operand >= MIN_INT16) && (Operand <= MAX_INT16)) {
+    *Result = (INT16)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INT16_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT64 -> UINT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToUint16 (
+  IN  INT64   Operand,
+  OUT UINT16  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Operand >= 0) && (Operand <= MAX_UINT16)) {
+    *Result = (UINT16)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT16_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT64 -> INT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToInt32 (
+  IN  INT64  Operand,
+  OUT INT32  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Operand >= MIN_INT32) && (Operand <= MAX_INT32)) {
+    *Result = (INT32)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INT32_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT64 -> UINT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToUint32 (
+  IN  INT64   Operand,
+  OUT UINT32  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Operand >= 0) && (Operand <= MAX_UINT32)) {
+    *Result = (UINT32)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT32_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  INT64 -> UINT64 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToUint64 (
+  IN  INT64   Operand,
+  OUT UINT64  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand >= 0) {
+    *Result = (UINT64)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT64_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT64 -> INT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64ToInt8 (
+  IN  UINT64  Operand,
+  OUT INT8    *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_INT8) {
+    *Result = (INT8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INT8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT64 -> CHAR8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64ToChar8 (
+  IN  UINT64  Operand,
+  OUT CHAR8   *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_INT8) {
+    *Result = (INT8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = CHAR8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT64 -> UINT8 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64ToUint8 (
+  IN  UINT64  Operand,
+  OUT UINT8   *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_UINT8) {
+    *Result = (UINT8)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT64 -> INT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64ToInt16 (
+  IN  UINT64  Operand,
+  OUT INT16   *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_INT16) {
+    *Result = (INT16)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INT16_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT64 -> UINT16 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64ToUint16 (
+  IN  UINT64  Operand,
+  OUT UINT16  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_UINT16) {
+    *Result = (UINT16)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT16_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT64 -> INT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64ToInt32 (
+  IN  UINT64  Operand,
+  OUT INT32   *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_INT32) {
+    *Result = (INT32)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INT32_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT64 -> UINT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64ToUint32 (
+  IN  UINT64  Operand,
+  OUT UINT32  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_UINT32) {
+    *Result = (UINT32)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT32_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT64 -> INTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64ToIntn (
+  IN  UINT64  Operand,
+  OUT INTN    *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_INTN) {
+    *Result = (INTN)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INTN_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT64 -> INT64 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64ToInt64 (
+  IN  UINT64  Operand,
+  OUT INT64   *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand <= MAX_INT64) {
+    *Result = (INT64)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = INT64_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+//
+// Addition functions
+//
+
+/**
+  UINT8 addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint8Add (
+  IN  UINT8  Augend,
+  IN  UINT8  Addend,
+  OUT UINT8  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (((UINT8)(Augend + Addend)) >= Augend) {
+    *Result = (UINT8)(Augend + Addend);
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT16 addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint16Add (
+  IN  UINT16  Augend,
+  IN  UINT16  Addend,
+  OUT UINT16  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (((UINT16)(Augend + Addend)) >= Augend) {
+    *Result = (UINT16)(Augend + Addend);
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT16_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT32 addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint32Add (
+  IN  UINT32  Augend,
+  IN  UINT32  Addend,
+  OUT UINT32  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Augend + Addend) >= Augend) {
+    *Result = (Augend + Addend);
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT32_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT64 addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64Add (
+  IN  UINT64  Augend,
+  IN  UINT64  Addend,
+  OUT UINT64  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Augend + Addend) >= Augend) {
+    *Result = (Augend + Addend);
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT64_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+//
+// Subtraction functions
+//
+
+/**
+  UINT8 subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint8Sub (
+  IN  UINT8  Minuend,
+  IN  UINT8  Subtrahend,
+  OUT UINT8  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Minuend >= Subtrahend) {
+    *Result = (UINT8)(Minuend - Subtrahend);
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT8_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT16 subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint16Sub (
+  IN  UINT16  Minuend,
+  IN  UINT16  Subtrahend,
+  OUT UINT16  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Minuend >= Subtrahend) {
+    *Result = (UINT16)(Minuend - Subtrahend);
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT16_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT32 subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint32Sub (
+  IN  UINT32  Minuend,
+  IN  UINT32  Subtrahend,
+  OUT UINT32  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Minuend >= Subtrahend) {
+    *Result = (Minuend - Subtrahend);
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT32_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINT64 subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64Sub (
+  IN  UINT64  Minuend,
+  IN  UINT64  Subtrahend,
+  OUT UINT64  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Minuend >= Subtrahend) {
+    *Result = (Minuend - Subtrahend);
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT64_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+//
+// Multiplication functions
+//
+
+/**
+  UINT8 multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint8Mult (
+  IN  UINT8  Multiplicand,
+  IN  UINT8  Multiplier,
+  OUT UINT8  *Result
+  )
+{
+  UINT32  IntermediateResult;
+
+  IntermediateResult = ((UINT32)Multiplicand) *((UINT32)Multiplier);
+
+  return SafeUint32ToUint8 (IntermediateResult, Result);
+}
+
+/**
+  UINT16 multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint16Mult (
+  IN  UINT16  Multiplicand,
+  IN  UINT16  Multiplier,
+  OUT UINT16  *Result
+  )
+{
+  UINT32  IntermediateResult;
+
+  IntermediateResult = ((UINT32)Multiplicand) *((UINT32)Multiplier);
+
+  return SafeUint32ToUint16 (IntermediateResult, Result);
+}
+
+/**
+  UINT32 multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint32Mult (
+  IN  UINT32  Multiplicand,
+  IN  UINT32  Multiplier,
+  OUT UINT32  *Result
+  )
+{
+  UINT64  IntermediateResult;
+
+  IntermediateResult = ((UINT64) Multiplicand) *((UINT64) Multiplier);
+
+  return SafeUint64ToUint32 (IntermediateResult, Result);
+}
+
+/**
+  UINT64 multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64Mult (
+  IN  UINT64  Multiplicand,
+  IN  UINT64  Multiplier,
+  OUT UINT64  *Result
+  )
+{
+  RETURN_STATUS  Status;
+  UINT32         DwordA;
+  UINT32         DwordB;
+  UINT32         DwordC;
+  UINT32         DwordD;
+  UINT64         ProductAD;
+  UINT64         ProductBC;
+  UINT64         ProductBD;
+  UINT64         UnsignedResult;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  ProductAD = 0;
+  ProductBC = 0;
+  ProductBD = 0;
+  UnsignedResult = 0;
+  Status = RETURN_BUFFER_TOO_SMALL;
+
+  //
+  // 64x64 into 128 is like 32.32 x 32.32.
+  //
+  // a.b * c.d = a*(c.d) + .b*(c.d) = a*c + a*.d + .b*c + .b*.d
+  // back in non-decimal notation where A=a*2^32 and C=c*2^32:
+  // A*C + A*d + b*C + b*d
+  // So there are four components to add together.
+  //   result = (a*c*2^64) + (a*d*2^32) + (b*c*2^32) + (b*d)
+  //
+  // a * c must be 0 or there would be bits in the high 64-bits
+  // a * d must be less than 2^32 or there would be bits in the high 64-bits
+  // b * c must be less than 2^32 or there would be bits in the high 64-bits
+  // then there must be no overflow of the resulting values summed up.
+  //
+  DwordA = (UINT32)(Multiplicand >> 32);
+  DwordC = (UINT32)(Multiplier >> 32);
+
+  //
+  // common case -- if high dwords are both zero, no chance for overflow
+  //
+  if ((DwordA == 0) && (DwordC == 0)) {
+    DwordB = (UINT32)Multiplicand;
+    DwordD = (UINT32)Multiplier;
+
+    *Result = (((UINT64)DwordB) *(UINT64)DwordD);
+    Status = RETURN_SUCCESS;
+  } else {
+    //
+    // a * c must be 0 or there would be bits set in the high 64-bits
+    //
+    if ((DwordA == 0) ||
+        (DwordC == 0)) {
+      DwordD = (UINT32)Multiplier;
+
+      //
+      // a * d must be less than 2^32 or there would be bits set in the high 64-bits
+      //
+      ProductAD = (((UINT64)DwordA) *(UINT64)DwordD);
+      if ((ProductAD & 0xffffffff00000000) == 0) {
+        DwordB = (UINT32)Multiplicand;
+
+        //
+        // b * c must be less than 2^32 or there would be bits set in the high 64-bits
+        //
+        ProductBC = (((UINT64)DwordB) *(UINT64)DwordC);
+        if ((ProductBC & 0xffffffff00000000) == 0) {
+          //
+          // now sum them all up checking for overflow.
+          // shifting is safe because we already checked for overflow above
+          //
+          if (!RETURN_ERROR (SafeUint64Add (ProductBC << 32, ProductAD << 32, &UnsignedResult))) {
+            //
+            // b * d
+            //
+            ProductBD = (((UINT64)DwordB) *(UINT64)DwordD);
+
+            if (!RETURN_ERROR (SafeUint64Add (UnsignedResult, ProductBD, &UnsignedResult))) {
+              *Result = UnsignedResult;
+              Status = RETURN_SUCCESS;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  if (RETURN_ERROR (Status)) {
+    *Result = UINT64_ERROR;
+  }
+  return Status;
+}
+
+//
+// Signed operations
+//
+// Strongly consider using unsigned numbers.
+//
+// Signed numbers are often used where unsigned numbers should be used.
+// For example file sizes and array indices should always be unsigned.
+// Subtracting a larger positive signed number from a smaller positive
+// signed number with SafeInt32Sub will succeed, producing a negative number,
+// that then must not be used as an array index (but can occasionally be
+// used as a pointer index.) Similarly for adding a larger magnitude
+// negative number to a smaller magnitude positive number.
+//
+// This library does not protect you from such errors. It tells you if your
+// integer operations overflowed, not if you are doing the right thing
+// with your non-overflowed integers.
+//
+// Likewise you can overflow a buffer with a non-overflowed unsigned index.
+//
+
+//
+// Signed addition functions
+//
+
+/**
+  INT8 Addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt8Add (
+  IN  INT8  Augend,
+  IN  INT8  Addend,
+  OUT INT8  *Result
+  )
+{
+  return SafeInt32ToInt8 (((INT32)Augend) + ((INT32)Addend), Result);
+}
+
+/**
+  CHAR8 Addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeChar8Add (
+  IN  CHAR8  Augend,
+  IN  CHAR8  Addend,
+  OUT CHAR8  *Result
+  )
+{
+  INT32  Augend32;
+  INT32  Addend32;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  Augend32 = (INT32)Augend;
+  Addend32 = (INT32)Addend;
+  if (Augend32 < 0 || Augend32 > MAX_INT8) {
+    *Result = CHAR8_ERROR;
+    return RETURN_BUFFER_TOO_SMALL;
+  }
+  if (Addend32 < 0 || Addend32 > MAX_INT8) {
+    *Result = CHAR8_ERROR;
+    return RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return SafeInt32ToChar8 (Augend32 + Addend32, Result);
+}
+
+/**
+  INT16 Addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt16Add (
+  IN  INT16  Augend,
+  IN  INT16  Addend,
+  OUT INT16  *Result
+  )
+{
+  return SafeInt32ToInt16 (((INT32)Augend) + ((INT32)Addend), Result);
+}
+
+/**
+  INT32 Addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32Add (
+  IN  INT32  Augend,
+  IN  INT32  Addend,
+  OUT INT32  *Result
+  )
+{
+  return SafeInt64ToInt32 (((INT64)Augend) + ((INT64)Addend), Result);
+}
+
+/**
+  INT64 Addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64Add (
+  IN  INT64  Augend,
+  IN  INT64  Addend,
+  OUT INT64  *Result
+  )
+{
+  RETURN_STATUS  Status;
+  INT64          SignedResult;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  SignedResult = Augend + Addend;
+
+  //
+  // Adding positive to negative never overflows.
+  // If you add two positive numbers, you expect a positive result.
+  // If you add two negative numbers, you expect a negative result.
+  // Overflow if inputs are the same sign and output is not that sign.
+  //
+  if (((Augend < 0) == (Addend < 0))  &&
+      ((Augend < 0) != (SignedResult < 0))) {
+    *Result = INT64_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  } else {
+    *Result = SignedResult;
+    Status = RETURN_SUCCESS;
+  }
+
+  return Status;
+}
+
+//
+// Signed subtraction functions
+//
+
+/**
+  INT8 Subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt8Sub (
+  IN  INT8  Minuend,
+  IN  INT8  Subtrahend,
+  OUT INT8  *Result
+  )
+{
+  return SafeInt32ToInt8 (((INT32)Minuend) - ((INT32)Subtrahend), Result);
+}
+
+/**
+  CHAR8 Subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeChar8Sub (
+  IN  CHAR8  Minuend,
+  IN  CHAR8  Subtrahend,
+  OUT CHAR8  *Result
+  )
+{
+  INT32  Minuend32;
+  INT32  Subtrahend32;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  Minuend32    = (INT32)Minuend;
+  Subtrahend32 = (INT32)Subtrahend;
+  if (Minuend32 < 0 || Minuend32 > MAX_INT8) {
+    *Result = CHAR8_ERROR;
+    return RETURN_BUFFER_TOO_SMALL;
+  }
+  if (Subtrahend32 < 0 || Subtrahend32 > MAX_INT8) {
+    *Result = CHAR8_ERROR;
+    return RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return SafeInt32ToChar8 (Minuend32 - Subtrahend32, Result);
+}
+
+/**
+  INT16 Subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt16Sub (
+  IN  INT16  Minuend,
+  IN  INT16  Subtrahend,
+  OUT INT16  *Result
+  )
+{
+  return SafeInt32ToInt16 (((INT32)Minuend) - ((INT32)Subtrahend), Result);
+}
+
+/**
+  INT32 Subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32Sub (
+  IN  INT32  Minuend,
+  IN  INT32  Subtrahend,
+  OUT INT32  *Result
+  )
+{
+  return SafeInt64ToInt32 (((INT64)Minuend) - ((INT64)Subtrahend), Result);
+}
+
+/**
+  INT64 Subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64Sub (
+  IN  INT64  Minuend,
+  IN  INT64  Subtrahend,
+  OUT INT64  *Result
+  )
+{
+  RETURN_STATUS  Status;
+  INT64          SignedResult;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  SignedResult = Minuend - Subtrahend;
+
+  //
+  // Subtracting a positive number from a positive number never overflows.
+  // Subtracting a negative number from a negative number never overflows.
+  // If you subtract a negative number from a positive number, you expect a positive result.
+  // If you subtract a positive number from a negative number, you expect a negative result.
+  // Overflow if inputs vary in sign and the output does not have the same sign as the first input.
+  //
+  if (((Minuend < 0) != (Subtrahend < 0)) &&
+      ((Minuend < 0) != (SignedResult < 0))) {
+    *Result = INT64_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  } else {
+    *Result = SignedResult;
+    Status = RETURN_SUCCESS;
+  }
+
+  return Status;
+}
+
+//
+// Signed multiplication functions
+//
+
+/**
+  INT8 multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt8Mult (
+  IN  INT8  Multiplicand,
+  IN  INT8  Multiplier,
+  OUT INT8  *Result
+  )
+{
+  return SafeInt32ToInt8 (((INT32)Multiplier) *((INT32)Multiplicand), Result);
+}
+
+/**
+  CHAR8 multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeChar8Mult (
+  IN  CHAR8  Multiplicand,
+  IN  CHAR8  Multiplier,
+  OUT CHAR8  *Result
+  )
+{
+  INT32  Multiplicand32;
+  INT32  Multiplier32;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  Multiplicand32 = (INT32)Multiplicand;
+  Multiplier32   = (INT32)Multiplier;
+  if (Multiplicand32 < 0 || Multiplicand32 > MAX_INT8) {
+    *Result = CHAR8_ERROR;
+    return RETURN_BUFFER_TOO_SMALL;
+  }
+  if (Multiplier32 < 0 || Multiplier32 > MAX_INT8) {
+    *Result = CHAR8_ERROR;
+    return RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return SafeInt32ToChar8 (Multiplicand32 * Multiplier32, Result);
+}
+
+/**
+  INT16 multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt16Mult (
+  IN  INT16  Multiplicand,
+  IN  INT16  Multiplier,
+  OUT INT16  *Result
+  )
+{
+  return SafeInt32ToInt16 (((INT32)Multiplicand) *((INT32)Multiplier), Result);
+}
+
+/**
+  INT32 multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32Mult (
+  IN  INT32  Multiplicand,
+  IN  INT32  Multiplier,
+  OUT INT32  *Result
+  )
+{
+  return SafeInt64ToInt32 (((INT64)Multiplicand) *((INT64)Multiplier), Result);
+}
+
+/**
+  INT64 multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64Mult (
+  IN  INT64  Multiplicand,
+  IN  INT64  Multiplier,
+  OUT INT64  *Result
+  )
+{
+  RETURN_STATUS  Status;
+  UINT64         UnsignedMultiplicand;
+  UINT64         UnsignedMultiplier;
+  UINT64         UnsignedResult;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  //
+  // Split into sign and magnitude, do unsigned operation, apply sign.
+  //
+  if (Multiplicand < 0) {
+    //
+    // Avoid negating the most negative number.
+    //
+    UnsignedMultiplicand = ((UINT64)(- (Multiplicand + 1))) + 1;
+  } else {
+    UnsignedMultiplicand = (UINT64)Multiplicand;
+  }
+
+  if (Multiplier < 0) {
+    //
+    // Avoid negating the most negative number.
+    //
+    UnsignedMultiplier = ((UINT64)(- (Multiplier + 1))) + 1;
+  } else {
+    UnsignedMultiplier = (UINT64)Multiplier;
+  }
+
+  Status = SafeUint64Mult (UnsignedMultiplicand, UnsignedMultiplier, &UnsignedResult);
+  if (!RETURN_ERROR (Status)) {
+    if ((Multiplicand < 0) != (Multiplier < 0)) {
+      if (UnsignedResult > MIN_INT64_MAGNITUDE) {
+        *Result = INT64_ERROR;
+        Status = RETURN_BUFFER_TOO_SMALL;
+      } else {
+        *Result = - ((INT64)UnsignedResult);
+      }
+    } else {
+      if (UnsignedResult > MAX_INT64) {
+        *Result = INT64_ERROR;
+        Status = RETURN_BUFFER_TOO_SMALL;
+      } else {
+        *Result = (INT64)UnsignedResult;
+      }
+    }
+  } else {
+    *Result = INT64_ERROR;
+  }
+  return Status;
+}
+
diff --git a/MdePkg/Library/BaseSafeIntLib/SafeIntLib32.c b/MdePkg/Library/BaseSafeIntLib/SafeIntLib32.c
new file mode 100644
index 000000000000..18bfb9e4130c
--- /dev/null
+++ b/MdePkg/Library/BaseSafeIntLib/SafeIntLib32.c
@@ -0,0 +1,554 @@
+/** @file
+  This library provides helper functions to prevent integer overflow during
+  type conversion, addition, subtraction, and multiplication.
+
+  Copyright (c) 2017, Microsoft Corporation
+
+  All rights reserved.
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+  1. Redistributions of source code must retain the above copyright notice,
+  this list of conditions and the following disclaimer.
+  2. Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+**/
+
+#include <Base.h>
+#include <Library/SafeIntLib.h>
+
+/**
+  INT32 -> UINTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32ToUintn (
+  IN  INT32  Operand,
+  OUT UINTN  *Result
+  )
+{
+  return SafeInt32ToUint32 (Operand, (UINT32 *)Result);
+}
+
+/**
+  UINT32 -> INTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint32ToIntn (
+  IN  UINT32  Operand,
+  OUT INTN    *Result
+  )
+{
+  return SafeUint32ToInt32 (Operand, (INT32 *)Result);
+}
+
+/**
+  INTN -> INT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnToInt32 (
+  IN  INTN   Operand,
+  OUT INT32  *Result
+  )
+{
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  *Result = (INT32)Operand;
+  return RETURN_SUCCESS;
+}
+
+/**
+  INTN -> UINT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnToUint32 (
+  IN  INTN    Operand,
+  OUT UINT32  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Operand >= 0) {
+    *Result = (UINT32)Operand;
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINT32_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINTN -> UINT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnToUint32 (
+  IN  UINTN   Operand,
+  OUT UINT32  *Result
+  )
+{
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  *Result = (UINT32)Operand;
+  return RETURN_SUCCESS;
+}
+
+/**
+  UINTN -> INT64 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnToInt64 (
+  IN  UINTN  Operand,
+  OUT INT64  *Result
+  )
+{
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  *Result = (INT64)Operand;
+  return RETURN_SUCCESS;
+}
+
+/**
+  INT64 -> INTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToIntn (
+  IN  INT64  Operand,
+  OUT INTN   *Result
+  )
+{
+  return SafeInt64ToInt32 (Operand, (INT32 *)Result);
+}
+
+/**
+  INT64 -> UINTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToUintn (
+  IN  INT64  Operand,
+  OUT UINTN  *Result
+  )
+{
+  return SafeInt64ToUint32 (Operand, (UINT32 *)Result);
+}
+
+/**
+  UINT64 -> UINTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64ToUintn (
+  IN  UINT64  Operand,
+  OUT UINTN   *Result
+  )
+{
+  return SafeUint64ToUint32 ((UINT64) Operand, (UINT32 *)Result);
+}
+
+/**
+  UINTN addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnAdd (
+  IN  UINTN  Augend,
+  IN  UINTN  Addend,
+  OUT UINTN  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((Augend + Addend) >= Augend) {
+    *Result = (Augend + Addend);
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINTN_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINTN subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnSub (
+  IN  UINTN  Minuend,
+  IN  UINTN  Subtrahend,
+  OUT UINTN  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (Minuend >= Subtrahend) {
+    *Result = (Minuend - Subtrahend);
+    Status = RETURN_SUCCESS;
+  } else {
+    *Result = UINTN_ERROR;
+    Status = RETURN_BUFFER_TOO_SMALL;
+  }
+
+  return Status;
+}
+
+/**
+  UINTN multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnMult (
+  IN  UINTN  Multiplicand,
+  IN  UINTN  Multiplier,
+  OUT UINTN  *Result
+  )
+{
+  UINT64  IntermediateResult;
+
+  IntermediateResult = ((UINT64) Multiplicand) *((UINT64) Multiplier);
+
+  return SafeUint64ToUintn (IntermediateResult, Result);
+}
+
+/**
+  INTN Addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnAdd (
+  IN  INTN  Augend,
+  IN  INTN  Addend,
+  OUT INTN  *Result
+  )
+{
+  return SafeInt64ToIntn (((INT64)Augend) + ((INT64)Addend), Result);
+}
+
+/**
+  INTN Subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnSub (
+  IN  INTN  Minuend,
+  IN  INTN  Subtrahend,
+  OUT INTN  *Result
+  )
+{
+  return SafeInt64ToIntn (((INT64)Minuend) - ((INT64)Subtrahend), Result);
+}
+
+/**
+  INTN multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnMult (
+  IN  INTN  Multiplicand,
+  IN  INTN  Multiplier,
+  OUT INTN  *Result
+  )
+{
+  return SafeInt64ToIntn (((INT64)Multiplicand) *((INT64)Multiplier), Result);
+}
+
diff --git a/MdePkg/Library/BaseSafeIntLib/SafeIntLib64.c b/MdePkg/Library/BaseSafeIntLib/SafeIntLib64.c
new file mode 100644
index 000000000000..b423c5cc1bdc
--- /dev/null
+++ b/MdePkg/Library/BaseSafeIntLib/SafeIntLib64.c
@@ -0,0 +1,508 @@
+/** @file
+  This library provides helper functions to prevent integer overflow during
+  type conversion, addition, subtraction, and multiplication.
+
+  Copyright (c) 2017, Microsoft Corporation
+
+  All rights reserved.
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+  1. Redistributions of source code must retain the above copyright notice,
+  this list of conditions and the following disclaimer.
+  2. Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+**/
+
+#include <Base.h>
+#include <Library/SafeIntLib.h>
+
+/**
+  INT32 -> UINTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32ToUintn (
+  IN  INT32  Operand,
+  OUT UINTN  *Result
+  )
+{
+  return SafeInt32ToUint64 (Operand, (UINT64 *) Result);
+}
+
+/**
+  UINT32 -> INTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint32ToIntn (
+  IN  UINT32  Operand,
+  OUT INTN    *Result
+  )
+{
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  *Result = Operand;
+  return RETURN_SUCCESS;
+}
+
+/**
+  INTN -> INT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnToInt32 (
+  IN  INTN   Operand,
+  OUT INT32  *Result
+  )
+{
+  return SafeInt64ToInt32 ((INT64) Operand, Result);
+}
+
+/**
+  INTN -> UINT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnToUint32 (
+  IN  INTN    Operand,
+  OUT UINT32  *Result
+  )
+{
+  return SafeInt64ToUint32 ((INT64)Operand, Result);
+}
+
+/**
+  UINTN -> UINT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnToUint32 (
+  IN  UINTN   Operand,
+  OUT UINT32  *Result
+  )
+{
+  return SafeUint64ToUint32 ((UINT64)Operand, Result);
+}
+
+/**
+  UINTN -> INT64 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnToInt64 (
+  IN  UINTN  Operand,
+  OUT INT64  *Result
+  )
+{
+  return SafeUint64ToInt64 ((UINT64)Operand, Result);
+}
+
+/**
+  INT64 -> INTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToIntn (
+  IN  INT64  Operand,
+  OUT INTN   *Result
+  )
+{
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  *Result = (INTN)Operand;
+  return RETURN_SUCCESS;
+}
+
+/**
+  INT64 -> UINTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToUintn (
+  IN  INT64  Operand,
+  OUT UINTN  *Result
+  )
+{
+  return SafeInt64ToUint64 (Operand, (UINT64 *)Result);
+}
+
+/**
+  UINT64 -> UINTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64ToUintn (
+  IN  UINT64  Operand,
+  OUT UINTN   *Result
+  )
+{
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  *Result = Operand;
+  return RETURN_SUCCESS;
+}
+
+/**
+  UINTN addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnAdd (
+  IN  UINTN  Augend,
+  IN  UINTN  Addend,
+  OUT UINTN  *Result
+  )
+{
+  return SafeUint64Add ((UINT64)Augend, (UINT64)Addend, (UINT64 *)Result);
+}
+
+/**
+  UINTN subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnSub (
+  IN  UINTN  Minuend,
+  IN  UINTN  Subtrahend,
+  OUT UINTN  *Result
+  )
+{
+  return SafeUint64Sub ((UINT64)Minuend, (UINT64)Subtrahend, (UINT64 *)Result);
+}
+
+/**
+  UINTN multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnMult (
+  IN  UINTN  Multiplicand,
+  IN  UINTN  Multiplier,
+  OUT UINTN  *Result
+  )
+{
+  return SafeUint64Mult ((UINT64)Multiplicand, (UINT64)Multiplier, (UINT64 *)Result);
+}
+
+/**
+  INTN Addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnAdd (
+  IN  INTN  Augend,
+  IN  INTN  Addend,
+  OUT INTN  *Result
+  )
+{
+  return SafeInt64Add ((INT64)Augend, (INT64)Addend, (INT64 *)Result);
+}
+
+/**
+  INTN Subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnSub (
+  IN  INTN  Minuend,
+  IN  INTN  Subtrahend,
+  OUT INTN  *Result
+  )
+{
+  return SafeInt64Sub ((INT64)Minuend, (INT64)Subtrahend, (INT64 *)Result);
+}
+
+/**
+  INTN multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnMult (
+  IN  INTN  Multiplicand,
+  IN  INTN  Multiplier,
+  OUT INTN  *Result
+  )
+{
+  return SafeInt64Mult ((INT64)Multiplicand, (INT64)Multiplier, (INT64 *)Result);
+}
+
diff --git a/MdePkg/Library/BaseSafeIntLib/SafeIntLibEbc.c b/MdePkg/Library/BaseSafeIntLib/SafeIntLibEbc.c
new file mode 100644
index 000000000000..4478957b7e33
--- /dev/null
+++ b/MdePkg/Library/BaseSafeIntLib/SafeIntLibEbc.c
@@ -0,0 +1,614 @@
+/** @file
+  This library provides helper functions to prevent integer overflow during
+  type conversion, addition, subtraction, and multiplication.
+
+  Copyright (c) 2017, Microsoft Corporation
+
+  All rights reserved.
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+  1. Redistributions of source code must retain the above copyright notice,
+  this list of conditions and the following disclaimer.
+  2. Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+**/
+
+#include <Base.h>
+#include <Library/SafeIntLib.h>
+
+/**
+  INT32 -> UINTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt32ToUintn (
+  IN  INT32  Operand,
+  OUT UINTN  *Result
+  )
+{
+  if (sizeof (UINTN) == sizeof (UINT32)) {
+    return SafeInt32ToUint32 (Operand, (UINT32 *)Result);
+  }
+  return SafeInt32ToUint64 (Operand, (UINT64 *) Result);
+}
+
+/**
+  UINT32 -> INTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint32ToIntn (
+  IN  UINT32  Operand,
+  OUT INTN    *Result
+  )
+{
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (sizeof (UINTN) == sizeof (UINT32)) {
+    return SafeUint32ToInt32 (Operand, (INT32 *)Result);
+  }
+  *Result = Operand;
+  return RETURN_SUCCESS;
+}
+
+/**
+  INTN -> INT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnToInt32 (
+  IN  INTN   Operand,
+  OUT INT32  *Result
+  )
+{
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (sizeof (UINTN) == sizeof (UINT32)) {
+    *Result = (INT32)Operand;
+    return RETURN_SUCCESS;
+  }
+  return SafeInt64ToInt32 ((INT64) Operand, Result);
+}
+
+/**
+  INTN -> UINT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnToUint32 (
+  IN  INTN    Operand,
+  OUT UINT32  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (sizeof (UINTN) == sizeof (UINT32)) {
+    if (Operand >= 0) {
+      *Result = (UINT32)Operand;
+      Status = RETURN_SUCCESS;
+    } else {
+      *Result = UINT32_ERROR;
+      Status = RETURN_BUFFER_TOO_SMALL;
+    }
+
+    return Status;
+  }
+  return SafeInt64ToUint32 ((INT64)Operand, Result);
+}
+
+/**
+  UINTN -> UINT32 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnToUint32 (
+  IN  UINTN   Operand,
+  OUT UINT32  *Result
+  )
+{
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (sizeof (UINTN) == sizeof (UINT32)) {
+    *Result = (UINT32)Operand;
+    return RETURN_SUCCESS;
+  }
+  return SafeUint64ToUint32 ((UINT64)Operand, Result);
+}
+
+/**
+  UINTN -> INT64 conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnToInt64 (
+  IN  UINTN  Operand,
+  OUT INT64  *Result
+  )
+{
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (sizeof (UINTN) == sizeof (UINT32)) {
+    *Result = (INT64)Operand;
+    return RETURN_SUCCESS;
+  }
+  return SafeUint64ToInt64 ((UINT64)Operand, Result);
+}
+
+/**
+  INT64 -> INTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToIntn (
+  IN  INT64  Operand,
+  OUT INTN   *Result
+  )
+{
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (sizeof (UINTN) == sizeof (UINT32)) {
+    return SafeInt64ToInt32 (Operand, (INT32 *)Result);
+  }
+  *Result = (INTN)Operand;
+  return RETURN_SUCCESS;
+}
+
+/**
+  INT64 -> UINTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeInt64ToUintn (
+  IN  INT64  Operand,
+  OUT UINTN  *Result
+  )
+{
+  if (sizeof (UINTN) == sizeof (UINT32)) {
+    return SafeInt64ToUint32 (Operand, (UINT32 *)Result);
+  }
+  return SafeInt64ToUint64 (Operand, (UINT64 *)Result);
+}
+
+/**
+  UINT64 -> UINTN conversion
+
+  Converts the value specified by Operand to a value specified by Result type
+  and stores the converted value into the caller allocated output buffer
+  specified by Result.  The caller must pass in a Result buffer that is at
+  least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the conversion results in an overflow or an underflow condition, then
+  Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Operand  Operand to be converted to new type
+  @param[out]  Result   Pointer to the result of conversion
+
+  @retval  RETURN_SUCCESS            Successful conversion
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUint64ToUintn (
+  IN  UINT64  Operand,
+  OUT UINTN   *Result
+  )
+{
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (sizeof (UINTN) == sizeof (UINT32)) {
+    return SafeUint64ToUint32 ((UINT64) Operand, (UINT32 *)Result);
+  }
+  *Result = Operand;
+  return RETURN_SUCCESS;
+}
+
+/**
+  UINTN addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnAdd (
+  IN  UINTN  Augend,
+  IN  UINTN  Addend,
+  OUT UINTN  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (sizeof (UINTN) == sizeof (UINT32)) {
+    if ((UINT32)(Augend + Addend) >= Augend) {
+      *Result = (Augend + Addend);
+      Status = RETURN_SUCCESS;
+    } else {
+      *Result = UINTN_ERROR;
+      Status = RETURN_BUFFER_TOO_SMALL;
+    }
+
+    return Status;
+  }
+  return SafeUint64Add ((UINT64)Augend, (UINT64)Addend, (UINT64 *)Result);
+}
+
+/**
+  UINTN subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnSub (
+  IN  UINTN  Minuend,
+  IN  UINTN  Subtrahend,
+  OUT UINTN  *Result
+  )
+{
+  RETURN_STATUS  Status;
+
+  if (Result == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (sizeof (UINTN) == sizeof (UINT32)) {
+    if (Minuend >= Subtrahend) {
+      *Result = (Minuend - Subtrahend);
+      Status = RETURN_SUCCESS;
+    } else {
+      *Result = UINTN_ERROR;
+      Status = RETURN_BUFFER_TOO_SMALL;
+    }
+
+    return Status;
+  }
+  return SafeUint64Sub ((UINT64)Minuend, (UINT64)Subtrahend, (UINT64 *)Result);
+}
+
+/**
+  UINTN multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeUintnMult (
+  IN  UINTN  Multiplicand,
+  IN  UINTN  Multiplier,
+  OUT UINTN  *Result
+  )
+{
+  UINT64  IntermediateResult;
+
+  if (sizeof (UINTN) == sizeof (UINT32)) {
+    IntermediateResult = ((UINT64) Multiplicand) *((UINT64) Multiplier);
+
+    return SafeUint64ToUintn (IntermediateResult, Result);
+  }
+  return SafeUint64Mult ((UINT64)Multiplicand, (UINT64)Multiplier, (UINT64 *)Result);
+}
+
+/**
+  INTN Addition
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Augend  A number to which addend will be added
+  @param[in]   Addend  A number to be added to another
+  @param[out]  Result  Pointer to the result of addition
+
+  @retval  RETURN_SUCCESS            Successful addition
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnAdd (
+  IN  INTN  Augend,
+  IN  INTN  Addend,
+  OUT INTN  *Result
+  )
+{
+  if (sizeof (UINTN) == sizeof (UINT32)) {
+    return SafeInt64ToIntn (((INT64)Augend) + ((INT64)Addend), Result);
+  }
+  return SafeInt64Add ((INT64)Augend, (INT64)Addend, (INT64 *)Result);
+}
+
+/**
+  INTN Subtraction
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Minuend     A number from which another is to be subtracted.
+  @param[in]   Subtrahend  A number to be subtracted from another
+  @param[out]  Result      Pointer to the result of subtraction
+
+  @retval  RETURN_SUCCESS            Successful subtraction
+  @retval  RETURN_BUFFER_TOO_SMALL   Underflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnSub (
+  IN  INTN  Minuend,
+  IN  INTN  Subtrahend,
+  OUT INTN  *Result
+  )
+{
+  if (sizeof (UINTN) == sizeof (UINT32)) {
+    return SafeInt64ToIntn (((INT64)Minuend) - ((INT64)Subtrahend), Result);
+  }
+  return SafeInt64Sub ((INT64)Minuend, (INT64)Subtrahend, (INT64 *)Result);
+}
+
+/**
+  INTN multiplication
+
+  Performs the requested operation using the input parameters into a value
+  specified by Result type and stores the converted value into the caller
+  allocated output buffer specified by Result.  The caller must pass in a
+  Result buffer that is at least as large as the Result type.
+
+  If Result is NULL, RETURN_INVALID_PARAMETER is returned.
+
+  If the requested operation results in an overflow or an underflow condition,
+  then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
+
+  @param[in]   Multiplicand  A number that is to be multiplied by another
+  @param[in]   Multiplier    A number by which the multiplicand is to be multiplied
+  @param[out]  Result        Pointer to the result of multiplication
+
+  @retval  RETURN_SUCCESS            Successful multiplication
+  @retval  RETURN_BUFFER_TOO_SMALL   Overflow
+  @retval  RETURN_INVALID_PARAMETER  Result is NULL
+**/
+RETURN_STATUS
+EFIAPI
+SafeIntnMult (
+  IN  INTN  Multiplicand,
+  IN  INTN  Multiplier,
+  OUT INTN  *Result
+  )
+{
+  if (sizeof (UINTN) == sizeof (UINT32)) {
+    return SafeInt64ToIntn (((INT64)Multiplicand) *((INT64)Multiplier), Result);
+  }
+  return SafeInt64Mult ((INT64)Multiplicand, (INT64)Multiplier, (INT64 *)Result);
+}
+
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index 603e498676ec..b4239507c89f 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -241,6 +241,11 @@ [LibraryClasses]
   ##  @libraryclass  provides EFI_FILE_HANDLE services
   FileHandleLib|Include/Library/FileHandleLib.h
 
+  ## @libraryclass provides helper functions to prevent integer overflow during
+  #                type conversion, addition, subtraction, and multiplication.
+  ##
+  SafeIntLib|Include/Library/SafeIntLib.h
+
 [LibraryClasses.IA32, LibraryClasses.X64]
   ##  @libraryclass  Abstracts both S/W SMI generation and detection.
   ##
diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc
index 8f5726350e6c..9b992036c52d 100644
--- a/MdePkg/MdePkg.dsc
+++ b/MdePkg/MdePkg.dsc
@@ -86,6 +86,7 @@ [Components]
   MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
   MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
   MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
+  MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
 
   MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
   MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
-- 
2.31.1


From 999d637156abdee7a6c10cafb054050f82a9f88d Mon Sep 17 00:00:00 2001
From: Liming Gao <liming.gao@intel.com>
Date: Wed, 31 Jan 2018 20:27:10 +0800
Subject: [PATCH 02/18] MdePkg SafeIntLib: Update API definition to use the
 same output name

In SafeUintnToChar8(), update its output parameter name.
Update pui8Result --> Result to match its library implementation

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Liming Gao <liming.gao@intel.com>
Reviewed-by: Michael Kinney <michael.d.kinney@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
(cherry picked from commit 93efab6d9a8e2278631752fad934425de0a6337a)
---
 MdePkg/Include/Library/SafeIntLib.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/MdePkg/Include/Library/SafeIntLib.h b/MdePkg/Include/Library/SafeIntLib.h
index 583930195a61..8c5003f67838 100644
--- a/MdePkg/Include/Library/SafeIntLib.h
+++ b/MdePkg/Include/Library/SafeIntLib.h
@@ -375,7 +375,7 @@ RETURN_STATUS
 EFIAPI
 SafeInt16ToUint8 (
   IN INT16 Operand,
-  OUT UINT8 *pui8Result
+  OUT UINT8 *Result
   );
 
 /**
@@ -564,7 +564,7 @@ RETURN_STATUS
 EFIAPI
 SafeUint16ToUint8 (
   IN UINT16 Operand,
-  OUT UINT8 *pui8Result
+  OUT UINT8 *Result
   );
 
 /**
@@ -672,7 +672,7 @@ RETURN_STATUS
 EFIAPI
 SafeInt32ToUint8 (
   IN INT32 Operand,
-  OUT UINT8 *pui8Result
+  OUT UINT8 *Result
   );
 
 /**
@@ -889,7 +889,7 @@ RETURN_STATUS
 EFIAPI
 SafeUint32ToUint8 (
   IN UINT32 Operand,
-  OUT UINT8 *pui8Result
+  OUT UINT8 *Result
   );
 
 /**
@@ -1078,7 +1078,7 @@ RETURN_STATUS
 EFIAPI
 SafeIntnToUint8 (
   IN INTN Operand,
-  OUT UINT8 *pui8Result
+  OUT UINT8 *Result
   );
 
 /**
@@ -1321,7 +1321,7 @@ RETURN_STATUS
 EFIAPI
 SafeUintnToUint8 (
   IN UINTN Operand,
-  OUT UINT8 *pui8Result
+  OUT UINT8 *Result
   );
 
 /**
-- 
2.31.1


From fa269ce1110c5905d9ea7ab6514868ea831d5b6d Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Thu, 15 Feb 2018 14:47:11 +0100
Subject: [PATCH 03/18] MdePkg/BaseSafeIntLib: fix undefined behavior in
 SafeInt64Sub()

The subtraction in the assignment

  SignedResult = Minuend - Subtrahend;

is performed with unchecked INT64 operands. According to ISO C, if the
mathematical result of signed integer subtraction cannot be represented in
the result type, the behavior is undefined. (Refer to ISO C99 6.5p5.
6.2.5p9 only exempts unsigned integers, and 6.3.1.3p3 does not apply
because it treats the conversion of integers that have been successfully
evaluated first.)

Replace the after-the-fact result checking with checks on the operands,
and only perform the subtraction if it is safe.

Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Michael D Kinney <michael.d.kinney@intel.com>
(cherry picked from commit 54c7728a04658b09ea1a50b9e35e838fde166003)
---
 MdePkg/Library/BaseSafeIntLib/SafeIntLib.c | 50 +++++++++++++++++-----
 1 file changed, 39 insertions(+), 11 deletions(-)

diff --git a/MdePkg/Library/BaseSafeIntLib/SafeIntLib.c b/MdePkg/Library/BaseSafeIntLib/SafeIntLib.c
index d846160ba0d1..8e857927b067 100644
--- a/MdePkg/Library/BaseSafeIntLib/SafeIntLib.c
+++ b/MdePkg/Library/BaseSafeIntLib/SafeIntLib.c
@@ -3837,27 +3837,55 @@ SafeInt64Sub (
   )
 {
   RETURN_STATUS  Status;
-  INT64          SignedResult;
 
   if (Result == NULL) {
     return RETURN_INVALID_PARAMETER;
   }
 
-  SignedResult = Minuend - Subtrahend;
-
   //
-  // Subtracting a positive number from a positive number never overflows.
-  // Subtracting a negative number from a negative number never overflows.
-  // If you subtract a negative number from a positive number, you expect a positive result.
-  // If you subtract a positive number from a negative number, you expect a negative result.
-  // Overflow if inputs vary in sign and the output does not have the same sign as the first input.
+  // * A Subtrahend of zero can never cause underflow or overflow.
   //
-  if (((Minuend < 0) != (Subtrahend < 0)) &&
-      ((Minuend < 0) != (SignedResult < 0))) {
+  // * A positive Subtrahend can only cause underflow. The underflow condition
+  //   is:
+  //
+  //     (Minuend - Subtrahend) < MIN_INT64
+  //
+  //   Adding Subtrahend to both sides yields
+  //
+  //     Minuend < (MIN_INT64 + Subtrahend)
+  //
+  //   This condition can be coded directly in C because the RHS will neither
+  //   underflow nor overflow. That is due to the starting condition:
+  //
+  //     0 < Subtrahend <= MAX_INT64
+  //
+  //   Adding MIN_INT64 to all three sides yields
+  //
+  //     MIN_INT64 < (MIN_INT64 + Subtrahend) <= (MIN_INT64 + MAX_INT64) = -1
+  //
+  // * A negative Subtrahend can only cause overflow. The overflow condition is
+  //
+  //     (Minuend - Subtrahend) > MAX_INT64
+  //
+  //   Adding Subtrahend to both sides yields
+  //
+  //     Minuend > (MAX_INT64 + Subtrahend)
+  //
+  //   This condition can be coded directly in C because the RHS will neither
+  //   underflow nor overflow. That is due to the starting condition:
+  //
+  //     MIN_INT64 <= Subtrahend < 0
+  //
+  //   Adding MAX_INT64 to all three sides yields
+  //
+  //     -1 = (MAX_INT64 + MIN_INT64) <= (MAX_INT64 + Subtrahend) < MAX_INT64
+  //
+  if (((Subtrahend > 0) && (Minuend < (MIN_INT64 + Subtrahend))) ||
+      ((Subtrahend < 0) && (Minuend > (MAX_INT64 + Subtrahend)))) {
     *Result = INT64_ERROR;
     Status = RETURN_BUFFER_TOO_SMALL;
   } else {
-    *Result = SignedResult;
+    *Result = Minuend - Subtrahend;
     Status = RETURN_SUCCESS;
   }
 
-- 
2.31.1


From 6be6a23b1c39eb48c4649d4a5344efc697c80608 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Thu, 15 Feb 2018 14:47:11 +0100
Subject: [PATCH 04/18] MdePkg/BaseSafeIntLib: fix undefined behavior in
 SafeInt64Add()

The addition in the assignment

  SignedResult = Augend + Addend;

is performed with unchecked INT64 operands. According to ISO C, if the
mathematical result of signed integer addition cannot be represented in
the result type, the behavior is undefined. (Refer to ISO C99 6.5p5.
6.2.5p9 only exempts unsigned integers, and 6.3.1.3p3 does not apply
because it treats the conversion of integers that have been successfully
evaluated first.)

Replace the after-the-fact result checking with checks on the operands,
and only perform the addition if it is safe.

Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Michael D Kinney <michael.d.kinney@intel.com>
(cherry picked from commit 41bfaffd13094d9042110091e6c37adf20c4032c)
---
 MdePkg/Library/BaseSafeIntLib/SafeIntLib.c | 56 ++++++++++++++++++----
 1 file changed, 46 insertions(+), 10 deletions(-)

diff --git a/MdePkg/Library/BaseSafeIntLib/SafeIntLib.c b/MdePkg/Library/BaseSafeIntLib/SafeIntLib.c
index 8e857927b067..56d97cf65601 100644
--- a/MdePkg/Library/BaseSafeIntLib/SafeIntLib.c
+++ b/MdePkg/Library/BaseSafeIntLib/SafeIntLib.c
@@ -3631,26 +3631,62 @@ SafeInt64Add (
   )
 {
   RETURN_STATUS  Status;
-  INT64          SignedResult;
 
   if (Result == NULL) {
     return RETURN_INVALID_PARAMETER;
   }
 
-  SignedResult = Augend + Addend;
-
   //
-  // Adding positive to negative never overflows.
-  // If you add two positive numbers, you expect a positive result.
-  // If you add two negative numbers, you expect a negative result.
-  // Overflow if inputs are the same sign and output is not that sign.
+  // * An Addend of zero can never cause underflow or overflow.
   //
-  if (((Augend < 0) == (Addend < 0))  &&
-      ((Augend < 0) != (SignedResult < 0))) {
+  // * A positive Addend can only cause overflow. The overflow condition is
+  //
+  //     (Augend + Addend) > MAX_INT64
+  //
+  //   Subtracting Addend from both sides yields
+  //
+  //     Augend > (MAX_INT64 - Addend)
+  //
+  //   This condition can be coded directly in C because the RHS will neither
+  //   underflow nor overflow. That is due to the starting condition:
+  //
+  //     0 < Addend <= MAX_INT64
+  //
+  //   Multiplying all three sides by (-1) yields
+  //
+  //     0 > (-Addend) >= (-MAX_INT64)
+  //
+  //   Adding MAX_INT64 to all three sides yields
+  //
+  //     MAX_INT64 > (MAX_INT64 - Addend) >= 0
+  //
+  // * A negative Addend can only cause underflow. The underflow condition is
+  //
+  //     (Augend + Addend) < MIN_INT64
+  //
+  //   Subtracting Addend from both sides yields
+  //
+  //     Augend < (MIN_INT64 - Addend)
+  //
+  //   This condition can be coded directly in C because the RHS will neither
+  //   underflow nor overflow. That is due to the starting condition:
+  //
+  //     MIN_INT64 <= Addend < 0
+  //
+  //   Multiplying all three sides by (-1) yields
+  //
+  //     (-MIN_INT64) >= (-Addend) > 0
+  //
+  //   Adding MIN_INT64 to all three sides yields
+  //
+  //     0 >= (MIN_INT64 - Addend) > MIN_INT64
+  //
+  if (((Addend > 0) && (Augend > (MAX_INT64 - Addend))) ||
+      ((Addend < 0) && (Augend < (MIN_INT64 - Addend)))) {
     *Result = INT64_ERROR;
     Status = RETURN_BUFFER_TOO_SMALL;
   } else {
-    *Result = SignedResult;
+    *Result = Augend + Addend;
     Status = RETURN_SUCCESS;
   }
 
-- 
2.31.1


From db10f161d3ecb393287a1b9ab51f5c842ca02eec Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Thu, 15 Feb 2018 17:09:43 +0100
Subject: [PATCH 05/18] MdePkg/BaseSafeIntLib: clean up parentheses in
 MIN_INT64_MAGNITUDE

The definition of the MIN_INT64_MAGNITUDE macro is correct, but it's
harder to read than necessary: the sub-expression

      (( (UINT64) - (MIN_INT64 + 1) ))

is doubly parenthesized. Reusing one pair of the outer parens, rewrite the
sub-expression (without change in meaning) so that the minus sign cannot
be mistaken for subtraction:

      ( (UINT64)(- (MIN_INT64 + 1)) )

The resultant macro definition matches the following expressions in
SafeInt64Mult():

>     //
>     // Avoid negating the most negative number.
>     //
>     UnsignedMultiplicand = ((UINT64)(- (Multiplicand + 1))) + 1;

and

>     //
>     // Avoid negating the most negative number.
>     //
>     UnsignedMultiplier = ((UINT64)(- (Multiplier + 1))) + 1;

Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Michael D Kinney <michael.d.kinney@intel.com>
(cherry picked from commit 8c33cc0ec926b17396fcd71686c727b991984d4a)
---
 MdePkg/Library/BaseSafeIntLib/SafeIntLib.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MdePkg/Library/BaseSafeIntLib/SafeIntLib.c b/MdePkg/Library/BaseSafeIntLib/SafeIntLib.c
index 56d97cf65601..de91ffeca2a5 100644
--- a/MdePkg/Library/BaseSafeIntLib/SafeIntLib.c
+++ b/MdePkg/Library/BaseSafeIntLib/SafeIntLib.c
@@ -33,7 +33,7 @@
 //
 // Magnitude of MIN_INT64 as expressed by a UINT64 number.
 //
-#define MIN_INT64_MAGNITUDE ((((UINT64) - (MIN_INT64 + 1))) + 1)
+#define MIN_INT64_MAGNITUDE (((UINT64)(- (MIN_INT64 + 1))) + 1)
 
 //
 // Conversion functions
-- 
2.31.1


From a22ebb786eaab51636df481243b08f5364961be2 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Thu, 15 Feb 2018 17:09:43 +0100
Subject: [PATCH 06/18] MdePkg/BaseSafeIntLib: fix undefined behavior in
 SafeInt64Mult()

If we have to negate UnsignedResult (due to exactly one of Multiplicand
and Multiplier being negative), and UnsignedResult is exactly
MIN_INT64_MAGNITUDE (value 2^63), then the statement

        *Result = - ((INT64)UnsignedResult);

invokes both implementation-defined behavior and undefined behavior.

First, MIN_INT64_MAGNITUDE is not representable as INT64, therefore the
result of the (inner) conversion

  (INT64)MIN_INT64_MAGNITUDE

is implementation-defined, or an implementation-defined signal is raised,
according to ISO C99 6.3.1.3p3.

Second, if we assume that the C language implementation defines the
conversion to INT64 simply as reinterpreting the bit pattern
0x8000_0000_0000_0000 as a signed integer in two's complement
representation, then the conversion immediately produces the negative
value MIN_INT64 (value -(2^63)). In turn, the (outer) negation

  -(MIN_INT64)

invokes undefined behavior, because the mathematical result of the
negation, namely 2^63, cannot be represented in an INT64 object. (Not even
mentioning the fact that the mathematical result would be incorrect.) In
practice, the undefined negation of MIN_INT64 happens to produce an
unchanged, valid-looking result on x86, i.e. (-(MIN_INT64)) == MIN_INT64.

We can summarize this as the undefined -- effectless -- negation canceling
out the botched -- auto-negating -- implementation-defined conversion.
Instead of relying on such behavior, dedicate a branch to this situation:
assign MIN_INT64 directly. The branch can be triggered e.g. by multiplying
(2^62) by (-2).

Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Michael D Kinney <michael.d.kinney@intel.com>
(cherry picked from commit 75505d161133cbeb57185b567d7b05756d255a3f)
---
 MdePkg/Library/BaseSafeIntLib/SafeIntLib.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MdePkg/Library/BaseSafeIntLib/SafeIntLib.c b/MdePkg/Library/BaseSafeIntLib/SafeIntLib.c
index de91ffeca2a5..c5f13d7e0828 100644
--- a/MdePkg/Library/BaseSafeIntLib/SafeIntLib.c
+++ b/MdePkg/Library/BaseSafeIntLib/SafeIntLib.c
@@ -4143,6 +4143,8 @@ SafeInt64Mult (
       if (UnsignedResult > MIN_INT64_MAGNITUDE) {
         *Result = INT64_ERROR;
         Status = RETURN_BUFFER_TOO_SMALL;
+      } else if (UnsignedResult == MIN_INT64_MAGNITUDE) {
+        *Result = MIN_INT64;
       } else {
         *Result = - ((INT64)UnsignedResult);
       }
-- 
2.31.1


From 69b56bb6d1db05bb687bbda9d84ef1512d2d6bff Mon Sep 17 00:00:00 2001
From: Jiaxin Wu <jiaxin.wu@intel.com>
Date: Fri, 4 May 2018 11:48:43 +0800
Subject: [PATCH 07/18] NetworkPkg/NetworkPkg.dsc: Add the instance of library
 class [SafeIntLib].

This patch is to add the instance of library class [SafeIntLib] to fix the
NetworkPkg build error, which is caused by the commit of 2167c7f7 that the
TlsLib will always consume SafeIntLib.

Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Long Qin <qin.long@intel.com>
Cc: Bi Dandan <dandan.bi@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
Reviewed-by: Long Qin <qin.long@intel.com>
(cherry picked from commit e9b4a4625c35f74824f05a2d846977756f7dd2a0)
---
 NetworkPkg/NetworkPkg.dsc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/NetworkPkg/NetworkPkg.dsc b/NetworkPkg/NetworkPkg.dsc
index b193f5f38bfd..bafcd4882d4a 100644
--- a/NetworkPkg/NetworkPkg.dsc
+++ b/NetworkPkg/NetworkPkg.dsc
@@ -45,6 +45,7 @@ [LibraryClasses]
   PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
   DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
   DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
 
   DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
   NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
-- 
2.31.1


From 43a81e1c770a67a23754b870a676866cc019269a Mon Sep 17 00:00:00 2001
From: Michael D Kinney <michael.d.kinney@intel.com>
Date: Fri, 29 Dec 2017 18:59:21 -0800
Subject: [PATCH 08/18] OvmfPkg: Add SafeIntLib and BmpSupportLib to DSC files

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

Based on content from the following branch/commits:
https://github.com/Microsoft/MS_UEFI/tree/share/MsCapsuleSupport
https://github.com/Microsoft/MS_UEFI/commit/33bab4031a417d7d5a7d356c15a14c2e60302b2d
https://github.com/Microsoft/MS_UEFI/commit/ca516b1a61315c2d823f453e12d2135098f53d61
https://github.com/Microsoft/MS_UEFI/commit/2b9f111f2e74a4c2ef4c4e32379e111f016dbd9b

The BootGraphicsResourceTableDxe module uses the BmpSupportLib
and SafeIntLib to convert a GOP BLT buffer to a BMP graphics image.
Add library mappings for these new library classes.

Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Bret Barkelew <Bret.Barkelew@microsoft.com>
(cherry picked from commit 7fc21c29e84b018898299e93cc2052fa5ad9bab0)

NOTE from Gary:
  Remove importing of BmpSupportLib since we only need SafeIntLib for
  bsc#1186151
---
 OvmfPkg/OvmfPkgIa32.dsc    | 1 +
 OvmfPkg/OvmfPkgIa32X64.dsc | 1 +
 OvmfPkg/OvmfPkgX64.dsc     | 1 +
 3 files changed, 3 insertions(+)

diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 7ccb61147f27..bc124cb3eb17 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -102,6 +102,7 @@ [LibraryClasses]
   PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
   BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
   BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
   SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
   CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
   PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 237ec71b5ec0..c58bc2006ca7 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -107,6 +107,7 @@ [LibraryClasses]
   PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
   BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
   BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
   SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
   CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
   PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index a5047fa38e61..4317f122c7bd 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -107,6 +107,7 @@ [LibraryClasses]
   PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
   BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
   BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
   SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
   CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
   PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
-- 
2.31.1


From ffd772ee01d2294cb9f045640ef719708536a039 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Mon, 26 Apr 2021 19:05:20 +0200
Subject: [PATCH 09/18] NetworkPkg/IScsiDxe: wrap IScsiCHAP source files to 80
 characters
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Working with overlong lines is difficult for me; rewrap the CHAP-related
source files in IScsiDxe to 80 characters width. No functional changes.

Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Maciej Rabeda <maciej.rabeda@linux.intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3356
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Philippe Mathieu-Daude <philmd@redhat.com>
Reviewed-by: Maciej Rabeda <maciej.rabeda@linux.intel.com>
---
 NetworkPkg/IScsiDxe/IScsiCHAP.c | 90 +++++++++++++++++++++++++--------
 NetworkPkg/IScsiDxe/IScsiCHAP.h |  3 +-
 2 files changed, 71 insertions(+), 22 deletions(-)

diff --git a/NetworkPkg/IScsiDxe/IScsiCHAP.c b/NetworkPkg/IScsiDxe/IScsiCHAP.c
index 18c49b952f56..5f045b07851c 100644
--- a/NetworkPkg/IScsiDxe/IScsiCHAP.c
+++ b/NetworkPkg/IScsiDxe/IScsiCHAP.c
@@ -1,5 +1,6 @@
 /** @file
-  This file is for Challenge-Handshake Authentication Protocol (CHAP) Configuration.
+  This file is for Challenge-Handshake Authentication Protocol (CHAP)
+  Configuration.
 
 Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
@@ -24,9 +25,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
   @param[in]   ChallengeLength    The length of iSCSI CHAP challenge message.
   @param[out]  ChapResponse       The calculation of the expected hash value.
   
-  @retval EFI_SUCCESS             The expected hash value was calculatedly successfully.
-  @retval EFI_PROTOCOL_ERROR      The length of the secret should be at least the
-                                  length of the hash value for the hashing algorithm chosen.
+  @retval EFI_SUCCESS             The expected hash value was calculatedly
+                                  successfully.
+  @retval EFI_PROTOCOL_ERROR      The length of the secret should be at least
+                                  the length of the hash value for the hashing
+                                  algorithm chosen.
   @retval EFI_PROTOCOL_ERROR      MD5 hash operation fail.
   @retval EFI_OUT_OF_RESOURCES    Fail to allocate resource to complete MD5.
 
@@ -100,8 +103,10 @@ Exit:
   @param[in]   AuthData             iSCSI CHAP authentication data. 
   @param[in]   TargetResponse       The response from target.    
 
-  @retval EFI_SUCCESS               The response from target passed authentication.
-  @retval EFI_SECURITY_VIOLATION    The response from target was not expected value.
+  @retval EFI_SUCCESS               The response from target passed
+                                    authentication.
+  @retval EFI_SECURITY_VIOLATION    The response from target was not expected
+                                    value.
   @retval Others                    Other errors as indicated.
 
 **/
@@ -199,7 +204,10 @@ IScsiCHAPOnRspReceived (
     //
     // The first Login Response.
     //
-    Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_TARGET_PORTAL_GROUP_TAG);
+    Value = IScsiGetValueByKeyFromList (
+              KeyValueList,
+              ISCSI_KEY_TARGET_PORTAL_GROUP_TAG
+              );
     if (Value == NULL) {
       goto ON_EXIT;
     }
@@ -211,13 +219,17 @@ IScsiCHAPOnRspReceived (
 
     Session->TargetPortalGroupTag = (UINT16) Result;
 
-    Value                         = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_AUTH_METHOD);
+    Value                         = IScsiGetValueByKeyFromList (
+                                      KeyValueList,
+                                      ISCSI_KEY_AUTH_METHOD
+                                      );
     if (Value == NULL) {
       goto ON_EXIT;
     }
     //
-    // Initiator mandates CHAP authentication but target replies without "CHAP", or
-    // initiator suggets "None" but target replies with some kind of auth method.
+    // Initiator mandates CHAP authentication but target replies without
+    // "CHAP", or initiator suggets "None" but target replies with some kind of
+    // auth method.
     //
     if (Session->AuthType == ISCSI_AUTH_TYPE_NONE) {
       if (AsciiStrCmp (Value, ISCSI_KEY_VALUE_NONE) != 0) {
@@ -242,7 +254,10 @@ IScsiCHAPOnRspReceived (
     //
     // The Target replies with CHAP_A=<A> CHAP_I=<I> CHAP_C=<C>
     //
-    Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_ALGORITHM);
+    Value = IScsiGetValueByKeyFromList (
+              KeyValueList,
+              ISCSI_KEY_CHAP_ALGORITHM
+              );
     if (Value == NULL) {
       goto ON_EXIT;
     }
@@ -255,12 +270,18 @@ IScsiCHAPOnRspReceived (
       goto ON_EXIT;
     }
 
-    Identifier = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_IDENTIFIER);
+    Identifier = IScsiGetValueByKeyFromList (
+                   KeyValueList,
+                   ISCSI_KEY_CHAP_IDENTIFIER
+                   );
     if (Identifier == NULL) {
       goto ON_EXIT;
     }
 
-    Challenge = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_CHALLENGE);
+    Challenge = IScsiGetValueByKeyFromList (
+                  KeyValueList,
+                  ISCSI_KEY_CHAP_CHALLENGE
+                  );
     if (Challenge == NULL) {
       goto ON_EXIT;
     }
@@ -275,7 +296,11 @@ IScsiCHAPOnRspReceived (
     
     AuthData->InIdentifier      = (UINT32) Result;
     AuthData->InChallengeLength = ISCSI_CHAP_AUTH_MAX_LEN;
-    IScsiHexToBin ((UINT8 *) AuthData->InChallenge, &AuthData->InChallengeLength, Challenge);
+    IScsiHexToBin (
+      (UINT8 *) AuthData->InChallenge,
+      &AuthData->InChallengeLength,
+      Challenge
+      );
     Status = IScsiCHAPCalculateResponse (
                AuthData->InIdentifier,
                AuthData->AuthConfig->CHAPSecret,
@@ -309,7 +334,10 @@ IScsiCHAPOnRspReceived (
       goto ON_EXIT;
     }
 
-    Response = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_RESPONSE);
+    Response = IScsiGetValueByKeyFromList (
+                 KeyValueList,
+                 ISCSI_KEY_CHAP_RESPONSE
+                 );
     if (Response == NULL) {
       goto ON_EXIT;
     }
@@ -347,7 +375,8 @@ ON_EXIT:
   @param[in, out]  Pdu         The PDU to send out.
 
   @retval EFI_SUCCESS           All check passed and the phase-related CHAP
-                                authentication info is filled into the iSCSI PDU.
+                                authentication info is filled into the iSCSI
+                                PDU.
   @retval EFI_OUT_OF_RESOURCES  Failed to allocate memory.
   @retval EFI_PROTOCOL_ERROR    Some kind of protocol error occurred.
 
@@ -398,7 +427,11 @@ IScsiCHAPToSendReq (
     // It's the initial Login Request. Fill in the key=value pairs mandatory
     // for the initial Login Request.
     //
-    IScsiAddKeyValuePair (Pdu, ISCSI_KEY_INITIATOR_NAME, mPrivate->InitiatorName);
+    IScsiAddKeyValuePair (
+      Pdu,
+      ISCSI_KEY_INITIATOR_NAME,
+      mPrivate->InitiatorName
+      );
     IScsiAddKeyValuePair (Pdu, ISCSI_KEY_SESSION_TYPE, "Normal");
     IScsiAddKeyValuePair (
       Pdu,
@@ -419,7 +452,8 @@ IScsiCHAPToSendReq (
 
   case ISCSI_CHAP_STEP_ONE:
     //
-    // First step, send the Login Request with CHAP_A=<A1,A2...> key-value pair.
+    // First step, send the Login Request with CHAP_A=<A1,A2...> key-value
+    // pair.
     //
     AsciiSPrint (ValueStr, sizeof (ValueStr), "%d", ISCSI_CHAP_ALGORITHM_MD5);
     IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_ALGORITHM, ValueStr);
@@ -435,11 +469,20 @@ IScsiCHAPToSendReq (
     //
     // CHAP_N=<N>
     //
-    IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_NAME, (CHAR8 *) &AuthData->AuthConfig->CHAPName);
+    IScsiAddKeyValuePair (
+      Pdu,
+      ISCSI_KEY_CHAP_NAME,
+      (CHAR8 *) &AuthData->AuthConfig->CHAPName
+      );
     //
     // CHAP_R=<R>
     //
-    IScsiBinToHex ((UINT8 *) AuthData->CHAPResponse, ISCSI_CHAP_RSP_LEN, Response, &RspLen);
+    IScsiBinToHex (
+      (UINT8 *) AuthData->CHAPResponse,
+      ISCSI_CHAP_RSP_LEN,
+      Response,
+      &RspLen
+      );
     IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_RESPONSE, Response);
 
     if (AuthData->AuthConfig->CHAPType == ISCSI_CHAP_MUTUAL) {
@@ -454,7 +497,12 @@ IScsiCHAPToSendReq (
       //
       IScsiGenRandom ((UINT8 *) AuthData->OutChallenge, ISCSI_CHAP_RSP_LEN);
       AuthData->OutChallengeLength = ISCSI_CHAP_RSP_LEN;
-      IScsiBinToHex ((UINT8 *) AuthData->OutChallenge, ISCSI_CHAP_RSP_LEN, Challenge, &ChallengeLen);
+      IScsiBinToHex (
+        (UINT8 *) AuthData->OutChallenge,
+        ISCSI_CHAP_RSP_LEN,
+        Challenge,
+        &ChallengeLen
+        );
       IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_CHALLENGE, Challenge);
 
       Conn->AuthStep = ISCSI_CHAP_STEP_FOUR;
diff --git a/NetworkPkg/IScsiDxe/IScsiCHAP.h b/NetworkPkg/IScsiDxe/IScsiCHAP.h
index 132461b84d25..59c53fcd3538 100644
--- a/NetworkPkg/IScsiDxe/IScsiCHAP.h
+++ b/NetworkPkg/IScsiDxe/IScsiCHAP.h
@@ -94,7 +94,8 @@ IScsiCHAPOnRspReceived (
   @param[in, out]  Pdu         The PDU to send out.
 
   @retval EFI_SUCCESS           All check passed and the phase-related CHAP
-                                authentication info is filled into the iSCSI PDU.
+                                authentication info is filled into the iSCSI
+                                PDU.
   @retval EFI_OUT_OF_RESOURCES  Failed to allocate memory.
   @retval EFI_PROTOCOL_ERROR    Some kind of protocol error occurred.
 
-- 
2.31.1


From fa23b21d2e383b0177401fd6ba1d4533668752d7 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Mon, 26 Apr 2021 20:07:25 +0200
Subject: [PATCH 10/18] NetworkPkg/IScsiDxe: simplify
 "ISCSI_CHAP_AUTH_DATA.InChallenge" size
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The ISCSI_CHAP_AUTH_MAX_LEN macro is defined with value 1024.

The usage of this macro currently involves a semantic (not functional)
bug, which we're going to fix in a subsequent patch, eliminating
ISCSI_CHAP_AUTH_MAX_LEN altogether.

For now, remove the macro's usage from all
"ISCSI_CHAP_AUTH_DATA.InChallenge" contexts. This is doable without
duplicating open-coded constants.

No changes in functionality.

Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Maciej Rabeda <maciej.rabeda@linux.intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3356
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Maciej Rabeda <maciej.rabeda@linux.intel.com>
---
 NetworkPkg/IScsiDxe/IScsiCHAP.c | 2 +-
 NetworkPkg/IScsiDxe/IScsiCHAP.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/NetworkPkg/IScsiDxe/IScsiCHAP.c b/NetworkPkg/IScsiDxe/IScsiCHAP.c
index 5f045b07851c..8a44078268c7 100644
--- a/NetworkPkg/IScsiDxe/IScsiCHAP.c
+++ b/NetworkPkg/IScsiDxe/IScsiCHAP.c
@@ -295,7 +295,7 @@ IScsiCHAPOnRspReceived (
     }    
     
     AuthData->InIdentifier      = (UINT32) Result;
-    AuthData->InChallengeLength = ISCSI_CHAP_AUTH_MAX_LEN;
+    AuthData->InChallengeLength = (UINT32) sizeof (AuthData->InChallenge);
     IScsiHexToBin (
       (UINT8 *) AuthData->InChallenge,
       &AuthData->InChallengeLength,
diff --git a/NetworkPkg/IScsiDxe/IScsiCHAP.h b/NetworkPkg/IScsiDxe/IScsiCHAP.h
index 59c53fcd3538..8692c78f1d36 100644
--- a/NetworkPkg/IScsiDxe/IScsiCHAP.h
+++ b/NetworkPkg/IScsiDxe/IScsiCHAP.h
@@ -55,7 +55,7 @@ typedef struct _ISCSI_CHAP_AUTH_CONFIG_NVDATA {
 typedef struct _ISCSI_CHAP_AUTH_DATA {
   ISCSI_CHAP_AUTH_CONFIG_NVDATA *AuthConfig;
   UINT32                        InIdentifier;
-  UINT8                         InChallenge[ISCSI_CHAP_AUTH_MAX_LEN];
+  UINT8                         InChallenge[1024];
   UINT32                        InChallengeLength;
   //
   // Calculated CHAP Response (CHAP_R) value.
-- 
2.31.1


From 07594eeab62504f17438a64776825aee045a0850 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Mon, 26 Apr 2021 20:17:23 +0200
Subject: [PATCH 11/18] NetworkPkg/IScsiDxe: clean up
 "ISCSI_CHAP_AUTH_DATA.OutChallengeLength"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The "ISCSI_CHAP_AUTH_DATA.OutChallenge" field is declared as a UINT8 array
with ISCSI_CHAP_AUTH_MAX_LEN (1024) elements. However, when the challenge
is generated and formatted, only ISCSI_CHAP_RSP_LEN (16) octets are used
in the array.

Change the array size to ISCSI_CHAP_RSP_LEN, and remove the (now unused)
ISCSI_CHAP_AUTH_MAX_LEN macro.

Remove the "ISCSI_CHAP_AUTH_DATA.OutChallengeLength" field, which is
superfluous too.

Most importantly, explain in a new comment *why* tying the challenge size
to the digest size (ISCSI_CHAP_RSP_LEN) has always made sense. (See also
Linux kernel commit 19f5f88ed779, "scsi: target: iscsi: tie the challenge
length to the hash digest size", 2019-11-06.) For sure, the motivation
that the new comment now explains has always been there, and has always
been the same, for IScsiDxe; it's just that now we spell it out too.

No change in peer-visible behavior.

Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Maciej Rabeda <maciej.rabeda@linux.intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3356
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Maciej Rabeda <maciej.rabeda@linux.intel.com>
---
 NetworkPkg/IScsiDxe/IScsiCHAP.c | 3 +--
 NetworkPkg/IScsiDxe/IScsiCHAP.h | 9 ++++++---
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/NetworkPkg/IScsiDxe/IScsiCHAP.c b/NetworkPkg/IScsiDxe/IScsiCHAP.c
index 8a44078268c7..320fd4c3b803 100644
--- a/NetworkPkg/IScsiDxe/IScsiCHAP.c
+++ b/NetworkPkg/IScsiDxe/IScsiCHAP.c
@@ -128,7 +128,7 @@ IScsiCHAPAuthTarget (
              AuthData->AuthConfig->ReverseCHAPSecret,
              SecretSize,
              AuthData->OutChallenge,
-             AuthData->OutChallengeLength,
+             ISCSI_CHAP_RSP_LEN,                      // ChallengeLength
              VerifyRsp
              );
 
@@ -496,7 +496,6 @@ IScsiCHAPToSendReq (
       // CHAP_C=<C>
       //
       IScsiGenRandom ((UINT8 *) AuthData->OutChallenge, ISCSI_CHAP_RSP_LEN);
-      AuthData->OutChallengeLength = ISCSI_CHAP_RSP_LEN;
       IScsiBinToHex (
         (UINT8 *) AuthData->OutChallenge,
         ISCSI_CHAP_RSP_LEN,
diff --git a/NetworkPkg/IScsiDxe/IScsiCHAP.h b/NetworkPkg/IScsiDxe/IScsiCHAP.h
index 8692c78f1d36..06ba084c9cee 100644
--- a/NetworkPkg/IScsiDxe/IScsiCHAP.h
+++ b/NetworkPkg/IScsiDxe/IScsiCHAP.h
@@ -25,7 +25,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 
 #define ISCSI_CHAP_ALGORITHM_MD5  5
 
-#define ISCSI_CHAP_AUTH_MAX_LEN   1024
 ///
 /// MD5_HASHSIZE
 ///
@@ -65,9 +64,13 @@ typedef struct _ISCSI_CHAP_AUTH_DATA {
   //
   // Auth-data to be sent out for mutual authentication.
   //
+  // While the challenge size is technically independent of the hashing
+  // algorithm, it is good practice to avoid hashing *fewer bytes* than the
+  // digest size. In other words, it's good practice to feed *at least as many
+  // bytes* to the hashing algorithm as the hashing algorithm will output.
+  //
   UINT32                        OutIdentifier;
-  UINT8                         OutChallenge[ISCSI_CHAP_AUTH_MAX_LEN];
-  UINT32                        OutChallengeLength;
+  UINT8                         OutChallenge[ISCSI_CHAP_RSP_LEN];
 } ISCSI_CHAP_AUTH_DATA;
 
 /**
-- 
2.31.1


From ea7b1bd5386925f8e02c0a49335a864b41763048 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Tue, 27 Apr 2021 09:49:16 +0200
Subject: [PATCH 12/18] NetworkPkg/IScsiDxe: clean up library class
 dependencies
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Sort the library class dependencies in the #include directives and in the
INF file. Remove the DpcLib class from the #include directives -- it is
not listed in the INF file, and IScsiDxe doesn't call either DpcLib API
(QueueDpc(), DispatchDpc()). No functional changes.

Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Maciej Rabeda <maciej.rabeda@linux.intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3356
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Maciej Rabeda <maciej.rabeda@linux.intel.com>
---
 NetworkPkg/IScsiDxe/IScsiDxe.inf |  6 +++---
 NetworkPkg/IScsiDxe/IScsiImpl.h  | 17 ++++++++---------
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/NetworkPkg/IScsiDxe/IScsiDxe.inf b/NetworkPkg/IScsiDxe/IScsiDxe.inf
index 319c7fe79a52..5ffb947abda0 100644
--- a/NetworkPkg/IScsiDxe/IScsiDxe.inf
+++ b/NetworkPkg/IScsiDxe/IScsiDxe.inf
@@ -71,6 +71,7 @@ [Packages]
   NetworkPkg/NetworkPkg.dec
 
 [LibraryClasses]
+  BaseCryptLib
   BaseLib
   BaseMemoryLib
   DebugLib
@@ -78,14 +79,13 @@ [LibraryClasses]
   HiiLib
   MemoryAllocationLib
   NetLib
-  TcpIoLib
   PrintLib
+  TcpIoLib
   UefiBootServicesTableLib
   UefiDriverEntryPoint
+  UefiHiiServicesLib
   UefiLib  
   UefiRuntimeServicesTableLib
-  UefiHiiServicesLib
-  BaseCryptLib
 
 [Protocols]
   gEfiAcpiTableProtocolGuid                     ## SOMETIMES_CONSUMES ## SystemTable
diff --git a/NetworkPkg/IScsiDxe/IScsiImpl.h b/NetworkPkg/IScsiDxe/IScsiImpl.h
index 9e36da020309..2b9a080b2ec1 100644
--- a/NetworkPkg/IScsiDxe/IScsiImpl.h
+++ b/NetworkPkg/IScsiDxe/IScsiImpl.h
@@ -41,21 +41,20 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Protocol/AdapterInformation.h>
 #include <Protocol/NetworkInterfaceIdentifier.h>
 
-#include <Library/HiiLib.h>
-#include <Library/UefiHiiServicesLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/DebugLib.h>
+#include <Library/BaseCryptLib.h>
 #include <Library/BaseLib.h>
 #include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
 #include <Library/MemoryAllocationLib.h>
+#include <Library/NetLib.h>
 #include <Library/PrintLib.h>
+#include <Library/TcpIoLib.h>
 #include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiHiiServicesLib.h>
 #include <Library/UefiLib.h>
-#include <Library/DpcLib.h>
-#include <Library/NetLib.h>
-#include <Library/TcpIoLib.h>
-#include <Library/BaseCryptLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
 
 #include <Guid/MdeModuleHii.h>
 #include <Guid/EventGroup.h>
-- 
2.31.1


From 4c018d9dc04a6f8ef4abe134149de5166f6692fa Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Tue, 27 Apr 2021 10:10:42 +0200
Subject: [PATCH 13/18] NetworkPkg/IScsiDxe: fix potential integer overflow in
 IScsiBinToHex()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Considering IScsiBinToHex():

>   if (((*HexLength) - 3) < BinLength * 2) {
>     *HexLength = BinLength * 2 + 3;
>   }

the following subexpressions are problematic:

  (*HexLength) - 3
  BinLength * 2
  BinLength * 2 + 3

The first one may wrap under zero, the latter two may wrap over
MAX_UINT32.

Rewrite the calculation using SafeIntLib.

While at it, change the type of the "Index" variable from UINTN to UINT32.
The largest "Index"-based value that we calculate is

  Index * 2 + 2                                (with (Index == BinLength))

Because the patch makes

  BinLength * 2 + 3

safe to calculate in UINT32, using UINT32 for

  Index * 2 + 2                                (with (Index == BinLength))

is safe too. Consistently using UINT32 improves readability.

This patch is best reviewed with "git show -W".

The integer overflows that this patch fixes are theoretical; a subsequent
patch in the series will audit the IScsiBinToHex() call sites, and show
that none of them can fail.

Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Maciej Rabeda <maciej.rabeda@linux.intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3356
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Maciej Rabeda <maciej.rabeda@linux.intel.com>
---
 NetworkPkg/IScsiDxe/IScsiDxe.inf |  1 +
 NetworkPkg/IScsiDxe/IScsiImpl.h  |  1 +
 NetworkPkg/IScsiDxe/IScsiMisc.c  | 19 +++++++++++++++----
 NetworkPkg/IScsiDxe/IScsiMisc.h  |  1 +
 4 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/NetworkPkg/IScsiDxe/IScsiDxe.inf b/NetworkPkg/IScsiDxe/IScsiDxe.inf
index 5ffb947abda0..3c356a22b856 100644
--- a/NetworkPkg/IScsiDxe/IScsiDxe.inf
+++ b/NetworkPkg/IScsiDxe/IScsiDxe.inf
@@ -80,6 +80,7 @@ [LibraryClasses]
   MemoryAllocationLib
   NetLib
   PrintLib
+  SafeIntLib
   TcpIoLib
   UefiBootServicesTableLib
   UefiDriverEntryPoint
diff --git a/NetworkPkg/IScsiDxe/IScsiImpl.h b/NetworkPkg/IScsiDxe/IScsiImpl.h
index 2b9a080b2ec1..a114b31549d7 100644
--- a/NetworkPkg/IScsiDxe/IScsiImpl.h
+++ b/NetworkPkg/IScsiDxe/IScsiImpl.h
@@ -50,6 +50,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Library/MemoryAllocationLib.h>
 #include <Library/NetLib.h>
 #include <Library/PrintLib.h>
+#include <Library/SafeIntLib.h>
 #include <Library/TcpIoLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 #include <Library/UefiHiiServicesLib.h>
diff --git a/NetworkPkg/IScsiDxe/IScsiMisc.c b/NetworkPkg/IScsiDxe/IScsiMisc.c
index 9e4164c986bc..23f2be3e085e 100644
--- a/NetworkPkg/IScsiDxe/IScsiMisc.c
+++ b/NetworkPkg/IScsiDxe/IScsiMisc.c
@@ -322,6 +322,7 @@ IScsiMacAddrToStr (
   @retval EFI_SUCCESS          The binary data is converted to the hexadecimal string 
                                and the length of the string is updated.
   @retval EFI_BUFFER_TOO_SMALL The string is too small.
+  @retval EFI_BAD_BUFFER_SIZE  BinLength is too large for hex encoding.
   @retval EFI_INVALID_PARAMETER The IP string is malformatted.
 
 **/
@@ -333,18 +334,28 @@ IScsiBinToHex (
   IN OUT UINT32 *HexLength
   )
 {
-  UINTN Index;
+  UINT32 HexLengthMin;
+  UINT32 HexLengthProvided;
+  UINT32 Index;
 
   if ((HexStr == NULL) || (BinBuffer == NULL) || (BinLength == 0)) {
     return EFI_INVALID_PARAMETER;
   }
 
-  if (((*HexLength) - 3) < BinLength * 2) {
-    *HexLength = BinLength * 2 + 3;
+  //
+  // Safely calculate: HexLengthMin := BinLength * 2 + 3.
+  //
+  if (RETURN_ERROR (SafeUint32Mult (BinLength, 2, &HexLengthMin)) ||
+      RETURN_ERROR (SafeUint32Add (HexLengthMin, 3, &HexLengthMin))) {
+    return EFI_BAD_BUFFER_SIZE;
+  }
+
+  HexLengthProvided = *HexLength;
+  *HexLength = HexLengthMin;
+  if (HexLengthProvided < HexLengthMin) {
     return EFI_BUFFER_TOO_SMALL;
   }
 
-  *HexLength = BinLength * 2 + 3;
   //
   // Prefix for Hex String.
   //
diff --git a/NetworkPkg/IScsiDxe/IScsiMisc.h b/NetworkPkg/IScsiDxe/IScsiMisc.h
index 659c0268b582..71312211f7b6 100644
--- a/NetworkPkg/IScsiDxe/IScsiMisc.h
+++ b/NetworkPkg/IScsiDxe/IScsiMisc.h
@@ -156,6 +156,7 @@ IScsiAsciiStrToIp (
   @retval EFI_SUCCESS          The binary data is converted to the hexadecimal string 
                                and the length of the string is updated.
   @retval EFI_BUFFER_TOO_SMALL The string is too small.
+  @retval EFI_BAD_BUFFER_SIZE  BinLength is too large for hex encoding.
   @retval EFI_INVALID_PARAMETER The IP string is malformatted.
 
 **/
-- 
2.31.1


From 6c9e2432cf976055d9b36729ffb8cf3a66721499 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Tue, 27 Apr 2021 10:26:01 +0200
Subject: [PATCH 14/18] NetworkPkg/IScsiDxe: assert that IScsiBinToHex() always
 succeeds
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

IScsiBinToHex() is called for encoding:

- the answer to the target's challenge; that is, CHAP_R;

- the challenge for the target, in case mutual authentication is enabled;
  that is, CHAP_C.

The initiator controls the size of both blobs, the sizes of their hex
encodings are correctly calculated in "RspLen" and "ChallengeLen".
Therefore the IScsiBinToHex() calls never fail; assert that.

Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Maciej Rabeda <maciej.rabeda@linux.intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3356
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Maciej Rabeda <maciej.rabeda@linux.intel.com>
---
 NetworkPkg/IScsiDxe/IScsiCHAP.c | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/NetworkPkg/IScsiDxe/IScsiCHAP.c b/NetworkPkg/IScsiDxe/IScsiCHAP.c
index 320fd4c3b803..03234b616594 100644
--- a/NetworkPkg/IScsiDxe/IScsiCHAP.c
+++ b/NetworkPkg/IScsiDxe/IScsiCHAP.c
@@ -397,6 +397,7 @@ IScsiCHAPToSendReq (
   UINT32                      RspLen;
   CHAR8                       *Challenge;
   UINT32                      ChallengeLen;
+  EFI_STATUS                  BinToHexStatus;
 
   ASSERT (Conn->CurrentStage == ISCSI_SECURITY_NEGOTIATION);
 
@@ -477,12 +478,13 @@ IScsiCHAPToSendReq (
     //
     // CHAP_R=<R>
     //
-    IScsiBinToHex (
-      (UINT8 *) AuthData->CHAPResponse,
-      ISCSI_CHAP_RSP_LEN,
-      Response,
-      &RspLen
-      );
+    BinToHexStatus = IScsiBinToHex (
+                       (UINT8 *) AuthData->CHAPResponse,
+                       ISCSI_CHAP_RSP_LEN,
+                       Response,
+                       &RspLen
+                       );
+    ASSERT_EFI_ERROR (BinToHexStatus);
     IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_RESPONSE, Response);
 
     if (AuthData->AuthConfig->CHAPType == ISCSI_CHAP_MUTUAL) {
@@ -496,12 +498,13 @@ IScsiCHAPToSendReq (
       // CHAP_C=<C>
       //
       IScsiGenRandom ((UINT8 *) AuthData->OutChallenge, ISCSI_CHAP_RSP_LEN);
-      IScsiBinToHex (
-        (UINT8 *) AuthData->OutChallenge,
-        ISCSI_CHAP_RSP_LEN,
-        Challenge,
-        &ChallengeLen
-        );
+      BinToHexStatus = IScsiBinToHex (
+                         (UINT8 *) AuthData->OutChallenge,
+                         ISCSI_CHAP_RSP_LEN,
+                         Challenge,
+                         &ChallengeLen
+                         );
+      ASSERT_EFI_ERROR (BinToHexStatus);
       IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_CHALLENGE, Challenge);
 
       Conn->AuthStep = ISCSI_CHAP_STEP_FOUR;
-- 
2.31.1


From 532d9764cde299860317d3b9fc245a37eb1fa5ba Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Tue, 27 Apr 2021 10:37:26 +0200
Subject: [PATCH 15/18] NetworkPkg/IScsiDxe: reformat IScsiHexToBin() leading
 comment block
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

We'll need further return values for IScsiHexToBin() in a subsequent
patch; make room for them in the leading comment block of the function.
While at it, rewrap the comment block to 80 characters width.

No functional changes.

Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Maciej Rabeda <maciej.rabeda@linux.intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3356
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Maciej Rabeda <maciej.rabeda@linux.intel.com>
---
 NetworkPkg/IScsiDxe/IScsiMisc.c | 14 +++++++-------
 NetworkPkg/IScsiDxe/IScsiMisc.h | 14 +++++++-------
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/NetworkPkg/IScsiDxe/IScsiMisc.c b/NetworkPkg/IScsiDxe/IScsiMisc.c
index 23f2be3e085e..d73d7ef32484 100644
--- a/NetworkPkg/IScsiDxe/IScsiMisc.c
+++ b/NetworkPkg/IScsiDxe/IScsiMisc.c
@@ -376,14 +376,14 @@ IScsiBinToHex (
 /**
   Convert the hexadecimal string into a binary encoded buffer.
 
-  @param[in, out]  BinBuffer   The binary buffer.
-  @param[in, out]  BinLength   Length of the binary buffer.
-  @param[in]       HexStr      The hexadecimal string.
-
-  @retval EFI_SUCCESS          The hexadecimal string is converted into a binary
-                               encoded buffer.
-  @retval EFI_BUFFER_TOO_SMALL The binary buffer is too small to hold the converted data.
+  @param[in, out]  BinBuffer    The binary buffer.
+  @param[in, out]  BinLength    Length of the binary buffer.
+  @param[in]       HexStr       The hexadecimal string.
 
+  @retval EFI_SUCCESS           The hexadecimal string is converted into a
+                                binary encoded buffer.
+  @retval EFI_BUFFER_TOO_SMALL  The binary buffer is too small to hold the
+                                converted data.
 **/
 EFI_STATUS
 IScsiHexToBin (
diff --git a/NetworkPkg/IScsiDxe/IScsiMisc.h b/NetworkPkg/IScsiDxe/IScsiMisc.h
index 71312211f7b6..13c165b88e42 100644
--- a/NetworkPkg/IScsiDxe/IScsiMisc.h
+++ b/NetworkPkg/IScsiDxe/IScsiMisc.h
@@ -171,14 +171,14 @@ IScsiBinToHex (
 /**
   Convert the hexadecimal string into a binary encoded buffer.
 
-  @param[in, out]  BinBuffer   The binary buffer.
-  @param[in, out]  BinLength   Length of the binary buffer.
-  @param[in]       HexStr      The hexadecimal string.
-
-  @retval EFI_SUCCESS          The hexadecimal string is converted into a binary
-                               encoded buffer.
-  @retval EFI_BUFFER_TOO_SMALL The binary buffer is too small to hold the converted data.
+  @param[in, out]  BinBuffer    The binary buffer.
+  @param[in, out]  BinLength    Length of the binary buffer.
+  @param[in]       HexStr       The hexadecimal string.
 
+  @retval EFI_SUCCESS           The hexadecimal string is converted into a
+                                binary encoded buffer.
+  @retval EFI_BUFFER_TOO_SMALL  The binary buffer is too small to hold the
+                                converted data.
 **/
 EFI_STATUS
 IScsiHexToBin (
-- 
2.31.1


From f6cc8d2cc922898a2086e2e2e7211cbdcdac8a60 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Tue, 27 Apr 2021 11:02:51 +0200
Subject: [PATCH 16/18] NetworkPkg/IScsiDxe: fix IScsiHexToBin() hex parsing
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The IScsiHexToBin() function has the following parser issues:

(1) If the *subject sequence* in "HexStr" is empty, the function returns
    EFI_SUCCESS (with "BinLength" set to 0 on output). Such inputs should
    be rejected.

(2) The function mis-handles a "HexStr" that ends with a stray nibble. For
    example, if "HexStr" is "0xABC", the function decodes it to the bytes
    {0xAB, 0x0C}, sets "BinLength" to 2 on output, and returns
    EFI_SUCCESS. Such inputs should be rejected.

(3) If an invalid hex char is found in "HexStr", the function treats it as
    end-of-hex-string, and returns EFI_SUCCESS. Such inputs should be
    rejected.

All of the above cases are remotely triggerable, as shown in a subsequent
patch, which adds error checking to the IScsiHexToBin() call sites. While
the initiator is not immediately compromised, incorrectly parsing CHAP_R
from the target, in case of mutual authentication, is not great.

Extend the interface contract of IScsiHexToBin() with
EFI_INVALID_PARAMETER, for reporting issues (1) through (3), and implement
the new checks.

Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Maciej Rabeda <maciej.rabeda@linux.intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3356
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Maciej Rabeda <maciej.rabeda@linux.intel.com>
---
 NetworkPkg/IScsiDxe/IScsiMisc.c | 12 ++++++++++--
 NetworkPkg/IScsiDxe/IScsiMisc.h |  1 +
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/NetworkPkg/IScsiDxe/IScsiMisc.c b/NetworkPkg/IScsiDxe/IScsiMisc.c
index d73d7ef32484..ebc2f4b7cd25 100644
--- a/NetworkPkg/IScsiDxe/IScsiMisc.c
+++ b/NetworkPkg/IScsiDxe/IScsiMisc.c
@@ -382,6 +382,7 @@ IScsiBinToHex (
 
   @retval EFI_SUCCESS           The hexadecimal string is converted into a
                                 binary encoded buffer.
+  @retval EFI_INVALID_PARAMETER Invalid hex encoding found in HexStr.
   @retval EFI_BUFFER_TOO_SMALL  The binary buffer is too small to hold the
                                 converted data.
 **/
@@ -408,14 +409,21 @@ IScsiHexToBin (
   
   Length = AsciiStrLen (HexStr);
 
+  //
+  // Reject an empty hex string; reject a stray nibble.
+  //
+  if (Length == 0 || Length % 2 != 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
   for (Index = 0; Index < Length; Index ++) {
     TemStr[0] = HexStr[Index];
     Digit = (UINT8) AsciiStrHexToUint64 (TemStr);
     if (Digit == 0 && TemStr[0] != '0') {
       //
-      // Invalid Lun Char.
+      // Invalid Hex Char.
       //
-      break;
+      return EFI_INVALID_PARAMETER;
     }
     if ((Index & 1) == 0) {
       BinBuffer [Index/2] = Digit;
diff --git a/NetworkPkg/IScsiDxe/IScsiMisc.h b/NetworkPkg/IScsiDxe/IScsiMisc.h
index 13c165b88e42..77e0f63d0ece 100644
--- a/NetworkPkg/IScsiDxe/IScsiMisc.h
+++ b/NetworkPkg/IScsiDxe/IScsiMisc.h
@@ -177,6 +177,7 @@ IScsiBinToHex (
 
   @retval EFI_SUCCESS           The hexadecimal string is converted into a
                                 binary encoded buffer.
+  @retval EFI_INVALID_PARAMETER Invalid hex encoding found in HexStr.
   @retval EFI_BUFFER_TOO_SMALL  The binary buffer is too small to hold the
                                 converted data.
 **/
-- 
2.31.1


From a82cb44f4c016ae3d4ecb7620eb1cb46a205b895 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Tue, 27 Apr 2021 11:02:51 +0200
Subject: [PATCH 17/18] NetworkPkg/IScsiDxe: fix IScsiHexToBin() buffer
 overflow
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The IScsiHexToBin() function documents the EFI_BUFFER_TOO_SMALL return
condition, but never actually checks whether the decoded buffer fits into
the caller-provided room (i.e., the input value of "BinLength"), and
EFI_BUFFER_TOO_SMALL is never returned. The decoding of "HexStr" can
overflow "BinBuffer".

This is remotely exploitable, as shown in a subsequent patch, which adds
error checking to the IScsiHexToBin() call sites. This issue allows the
target to compromise the initiator.

Introduce EFI_BAD_BUFFER_SIZE, in addition to the existent
EFI_BUFFER_TOO_SMALL, for reporting a special case of the buffer overflow,
plus actually catch the buffer overflow.

Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Maciej Rabeda <maciej.rabeda@linux.intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3356
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Maciej Rabeda <maciej.rabeda@linux.intel.com>
---
 NetworkPkg/IScsiDxe/IScsiMisc.c | 20 +++++++++++++++++---
 NetworkPkg/IScsiDxe/IScsiMisc.h |  3 +++
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/NetworkPkg/IScsiDxe/IScsiMisc.c b/NetworkPkg/IScsiDxe/IScsiMisc.c
index ebc2f4b7cd25..ba611ad3cd61 100644
--- a/NetworkPkg/IScsiDxe/IScsiMisc.c
+++ b/NetworkPkg/IScsiDxe/IScsiMisc.c
@@ -383,6 +383,9 @@ IScsiBinToHex (
   @retval EFI_SUCCESS           The hexadecimal string is converted into a
                                 binary encoded buffer.
   @retval EFI_INVALID_PARAMETER Invalid hex encoding found in HexStr.
+  @retval EFI_BAD_BUFFER_SIZE   The length of HexStr is too large for decoding:
+                                the decoded size cannot be expressed in
+                                BinLength on output.
   @retval EFI_BUFFER_TOO_SMALL  The binary buffer is too small to hold the
                                 converted data.
 **/
@@ -393,6 +396,8 @@ IScsiHexToBin (
   IN     CHAR8  *HexStr
   )
 {
+  UINTN   BinLengthMin;
+  UINT32  BinLengthProvided;
   UINTN   Index;
   UINTN   Length;
   UINT8   Digit;
@@ -415,6 +420,18 @@ IScsiHexToBin (
   if (Length == 0 || Length % 2 != 0) {
     return EFI_INVALID_PARAMETER;
   }
+  //
+  // Check if the caller provides enough room for the decoded blob.
+  //
+  BinLengthMin = Length / 2;
+  if (BinLengthMin > MAX_UINT32) {
+    return EFI_BAD_BUFFER_SIZE;
+  }
+  BinLengthProvided = *BinLength;
+  *BinLength = (UINT32)BinLengthMin;
+  if (BinLengthProvided < BinLengthMin) {
+    return EFI_BUFFER_TOO_SMALL;
+  }
 
   for (Index = 0; Index < Length; Index ++) {
     TemStr[0] = HexStr[Index];
@@ -431,9 +448,6 @@ IScsiHexToBin (
       BinBuffer [Index/2] = (UINT8) ((BinBuffer [Index/2] << 4) + Digit);
     }
   }
-  
-  *BinLength = (UINT32) ((Index + 1)/2);
-
   return EFI_SUCCESS;
 }
 
diff --git a/NetworkPkg/IScsiDxe/IScsiMisc.h b/NetworkPkg/IScsiDxe/IScsiMisc.h
index 77e0f63d0ece..d09e281c90c4 100644
--- a/NetworkPkg/IScsiDxe/IScsiMisc.h
+++ b/NetworkPkg/IScsiDxe/IScsiMisc.h
@@ -178,6 +178,9 @@ IScsiBinToHex (
   @retval EFI_SUCCESS           The hexadecimal string is converted into a
                                 binary encoded buffer.
   @retval EFI_INVALID_PARAMETER Invalid hex encoding found in HexStr.
+  @retval EFI_BAD_BUFFER_SIZE   The length of HexStr is too large for decoding:
+                                the decoded size cannot be expressed in
+                                BinLength on output.
   @retval EFI_BUFFER_TOO_SMALL  The binary buffer is too small to hold the
                                 converted data.
 **/
-- 
2.31.1


From 1b02f0d8380ce2efa13da777b02ae89b08712a38 Mon Sep 17 00:00:00 2001
From: Laszlo Ersek <lersek@redhat.com>
Date: Tue, 27 Apr 2021 12:10:12 +0200
Subject: [PATCH 18/18] NetworkPkg/IScsiDxe: check IScsiHexToBin() return
 values
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

IScsiDxe (that is, the initiator) receives two hex-encoded strings from
the iSCSI target:

- CHAP_C, where the target challenges the initiator,

- CHAP_R, where the target answers the challenge from the initiator (in
  case the initiator wants mutual authentication).

Accordingly, we have two IScsiHexToBin() call sites:

- At the CHAP_C decoding site, check whether the decoding succeeds. The
  decoded buffer ("AuthData->InChallenge") can accommodate 1024 bytes,
  which is a permissible restriction on the target, per
  <https://tools.ietf.org/html/rfc7143#section-12.1.3>. Shorter challenges
  from the target are acceptable.

- At the CHAP_R decoding site, enforce that the decoding both succeed, and
  provide exactly ISCSI_CHAP_RSP_LEN bytes. CHAP_R contains the digest
  calculated by the target, therefore it must be of fixed size. We may
  only call IScsiCHAPAuthTarget() if "TargetRsp" has been fully populated.

Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Maciej Rabeda <maciej.rabeda@linux.intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3356
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Maciej Rabeda <maciej.rabeda@linux.intel.com>
---
 NetworkPkg/IScsiDxe/IScsiCHAP.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/NetworkPkg/IScsiDxe/IScsiCHAP.c b/NetworkPkg/IScsiDxe/IScsiCHAP.c
index 03234b616594..f89d256bc110 100644
--- a/NetworkPkg/IScsiDxe/IScsiCHAP.c
+++ b/NetworkPkg/IScsiDxe/IScsiCHAP.c
@@ -296,11 +296,15 @@ IScsiCHAPOnRspReceived (
     
     AuthData->InIdentifier      = (UINT32) Result;
     AuthData->InChallengeLength = (UINT32) sizeof (AuthData->InChallenge);
-    IScsiHexToBin (
-      (UINT8 *) AuthData->InChallenge,
-      &AuthData->InChallengeLength,
-      Challenge
-      );
+    Status = IScsiHexToBin (
+               (UINT8 *) AuthData->InChallenge,
+               &AuthData->InChallengeLength,
+               Challenge
+               );
+    if (EFI_ERROR (Status)) {
+      Status = EFI_PROTOCOL_ERROR;
+      goto ON_EXIT;
+    }
     Status = IScsiCHAPCalculateResponse (
                AuthData->InIdentifier,
                AuthData->AuthConfig->CHAPSecret,
@@ -343,7 +347,11 @@ IScsiCHAPOnRspReceived (
     }
 
     RspLen = ISCSI_CHAP_RSP_LEN;
-    IScsiHexToBin (TargetRsp, &RspLen, Response);
+    Status = IScsiHexToBin (TargetRsp, &RspLen, Response);
+    if (EFI_ERROR (Status) || RspLen != ISCSI_CHAP_RSP_LEN) {
+      Status = EFI_PROTOCOL_ERROR;
+      goto ON_EXIT;
+    }
 
     //
     // Check the CHAP Name and Response replied by Target.
-- 
2.31.1

openSUSE Build Service is sponsored by