From 38093490dcaa713eabe5ec459c3472cb4b4ea01a 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 4aa1a785ced6..576bb72b15ea 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 3310029f5fc6..c4199066439e 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -233,6 +233,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 8b69de32a69d..855e2db48077 100644
--- a/MdePkg/MdePkg.dsc
+++ b/MdePkg/MdePkg.dsc
@@ -82,6 +82,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 f4c91433d689952a64d0dbde94c686709894b9e3 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 bbc7c0dee0d75cc7629a9596310a20730584af73 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 6fc9b4fabd3d6ac7ebebc3b5901266f66b320e63 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 6a3a37b47486428f8d0aae26f4277383435cfa45 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 d2b194d46f865a3d7748ff725add8879cc6cd75d 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 7f65154c6b24012c46245c29f30fe0e6a71cc9c5 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 b8e071b0a93d..8f195e1428c9 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 866166d87a69b9436cf03b47d89dfaf32d62c5ef 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 0796b0db816b..cfbf361ce583 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -81,6 +81,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 71ac62f023b5..33e379bb70cb 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -86,6 +86,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 2ceb31d7ffd5..1fc9c012b0e7 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -86,6 +86,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 1ab61d024e38374656634a7bc0bc7b216fb872dd 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 4587bafad8b0e6035888864ab0def798a0b4f5da 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 8f7ce4a6ad7559a805b73953ce3e08d77de49ec6 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 7457128642e3e1aa6f767009fae7e92f8569a140 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 c9b724bd3033..52831a9d6707 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 741c49784ade..2e36609335ea 100644
--- a/NetworkPkg/IScsiDxe/IScsiImpl.h
+++ b/NetworkPkg/IScsiDxe/IScsiImpl.h
@@ -40,21 +40,20 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Protocol/ScsiPassThruExt.h>
 #include <Protocol/AdapterInformation.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 f6414736d336c1bcd9e2ee6357b67d9c1cc94dbe 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 52831a9d6707..40bd1c145547 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 2e36609335ea..5d9312468cf4 100644
--- a/NetworkPkg/IScsiDxe/IScsiImpl.h
+++ b/NetworkPkg/IScsiDxe/IScsiImpl.h
@@ -49,6 +49,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 2c93590deb12..e93d1cf5aff2 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 caa2f94bb1b9..6f5cc9674fe6 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 056de669d6bda93a3b64b7b7db125ee0b64bf2cc 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 5ed275f48e68954057fb4afa728ffe3c48fef94e 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 e93d1cf5aff2..d1ecc877867e 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 6f5cc9674fe6..3108b06956ff 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 350a89a9fac69ce799581291fe307aefef59fa4c 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 d1ecc877867e..cce4bf1651df 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 3108b06956ff..12daebd05cc3 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 66315b780b8c8ab018624871ab5005bbd7f43f36 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 cce4bf1651df..4cdfc27a1a55 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 12daebd05cc3..6c0dbdf1e3cc 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 8d1ef395b962a691bfaca7b17cf40028da222209 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

