public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance
@ 2017-12-19 19:36 Kinney, Michael D
  2018-01-18  8:09 ` Sean Brogan
  2018-02-08  0:32 ` Laszlo Ersek
  0 siblings, 2 replies; 16+ messages in thread
From: Kinney, Michael D @ 2017-12-19 19:36 UTC (permalink / raw)
  To: edk2-devel; +Cc: Sean Brogan, Liming Gao, Michael D Kinney

From: Sean Brogan <sean.brogan@microsoft.com>

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.

Cc: Sean Brogan <sean.brogan@microsoft.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>
---
 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 +
 MdePkg/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 7b0f0ff32f..bc473562f9 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 42ea2f3055..c30d353f40 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 4fd5161f50..feda3eaaf4 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 da8b1a6d80..ed41648913 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 aeecf3fa9f..1f9b56a8cb 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 51885ca613..bfbae01abb 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 0000000000..583930195a
--- /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 e637d8649f..38ef266539 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 0000000000..20a83ed97b
--- /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 0000000000..d846160ba0
--- /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 0000000000..18bfb9e413
--- /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 0000000000..b423c5cc1b
--- /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 0000000000..4478957b7e
--- /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 603e498676..b4239507c8 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -241,6 +241,11 @@
   ##  @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 8f5726350e..9b992036c5 100644
--- a/MdePkg/MdePkg.dsc
+++ b/MdePkg/MdePkg.dsc
@@ -86,6 +86,7 @@
   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.14.2.windows.3



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance
  2017-12-19 19:36 [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance Kinney, Michael D
@ 2018-01-18  8:09 ` Sean Brogan
  2018-01-19  7:48   ` Gao, Liming
  2018-02-08  0:32 ` Laszlo Ersek
  1 sibling, 1 reply; 16+ messages in thread
From: Sean Brogan @ 2018-01-18  8:09 UTC (permalink / raw)
  To: Kinney, Michael D, edk2-devel@lists.01.org; +Cc: Gao, Liming

Reviewed-by: Sean Brogan <sean.brogan@microsoft.com>

-----Original Message-----
From: Kinney, Michael D [mailto:michael.d.kinney@intel.com] 
Sent: Tuesday, December 19, 2017 11:36 AM
To: edk2-devel@lists.01.org
Cc: Sean Brogan <sean.brogan@microsoft.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
Subject: [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance

From: Sean Brogan <sean.brogan@microsoft.com>

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.

Cc: Sean Brogan <sean.brogan@microsoft.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>
---
 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 +
 MdePkg/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 7b0f0ff32f..bc473562f9 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 42ea2f3055..c30d353f40 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 4fd5161f50..feda3eaaf4 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 da8b1a6d80..ed41648913 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 aeecf3fa9f..1f9b56a8cb 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 51885ca613..bfbae01abb 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 0000000000..583930195a
--- /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 e637d8649f..38ef266539 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 0000000000..20a83ed97b
--- /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 0000000000..d846160ba0
--- /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 0000000000..18bfb9e413
--- /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 0000000000..b423c5cc1b
--- /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 0000000000..4478957b7e
--- /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 603e498676..b4239507c8 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -241,6 +241,11 @@
   ##  @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 8f5726350e..9b992036c5 100644
--- a/MdePkg/MdePkg.dsc
+++ b/MdePkg/MdePkg.dsc
@@ -86,6 +86,7 @@
   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.14.2.windows.3



^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance
  2018-01-18  8:09 ` Sean Brogan
@ 2018-01-19  7:48   ` Gao, Liming
  0 siblings, 0 replies; 16+ messages in thread
From: Gao, Liming @ 2018-01-19  7:48 UTC (permalink / raw)
  To: Sean Brogan, Kinney, Michael D, edk2-devel@lists.01.org

Reviewed-by: Liming Gao <liming.gao@intel.com>

>-----Original Message-----
>From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
>Sean Brogan
>Sent: Thursday, January 18, 2018 4:09 PM
>To: Kinney, Michael D <michael.d.kinney@intel.com>; edk2-
>devel@lists.01.org
>Cc: Gao, Liming <liming.gao@intel.com>
>Subject: Re: [edk2] [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and
>instance
>
>Reviewed-by: Sean Brogan <sean.brogan@microsoft.com>
>
>-----Original Message-----
>From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]
>Sent: Tuesday, December 19, 2017 11:36 AM
>To: edk2-devel@lists.01.org
>Cc: Sean Brogan <sean.brogan@microsoft.com>; Gao, Liming
><liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>
>Subject: [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance
>
>From: Sean Brogan <sean.brogan@microsoft.com>
>
>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.
>
>Cc: Sean Brogan <sean.brogan@microsoft.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>
>---
> 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 +
> MdePkg/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 7b0f0ff32f..bc473562f9 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 42ea2f3055..c30d353f40 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 4fd5161f50..feda3eaaf4 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 da8b1a6d80..ed41648913 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 aeecf3fa9f..1f9b56a8cb 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 51885ca613..bfbae01abb 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 0000000000..583930195a
>--- /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 e637d8649f..38ef266539 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 0000000000..20a83ed97b
>--- /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 0000000000..d846160ba0
>--- /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 0000000000..18bfb9e413
>--- /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 0000000000..b423c5cc1b
>--- /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 0000000000..4478957b7e
>--- /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 603e498676..b4239507c8 100644
>--- a/MdePkg/MdePkg.dec
>+++ b/MdePkg/MdePkg.dec
>@@ -241,6 +241,11 @@
>   ##  @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 8f5726350e..9b992036c5 100644
>--- a/MdePkg/MdePkg.dsc
>+++ b/MdePkg/MdePkg.dsc
>@@ -86,6 +86,7 @@
>   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.14.2.windows.3
>
>_______________________________________________
>edk2-devel mailing list
>edk2-devel@lists.01.org
>https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance
  2017-12-19 19:36 [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance Kinney, Michael D
  2018-01-18  8:09 ` Sean Brogan
@ 2018-02-08  0:32 ` Laszlo Ersek
  2018-02-08  0:45   ` Laszlo Ersek
  1 sibling, 1 reply; 16+ messages in thread
From: Laszlo Ersek @ 2018-02-08  0:32 UTC (permalink / raw)
  To: Kinney, Michael D, edk2-devel; +Cc: Liming Gao, Sean Brogan

On 12/19/17 20:36, Kinney, Michael D wrote:
> From: Sean Brogan <sean.brogan@microsoft.com>
> 
> SafeIntLib provides helper functions to prevent integer overflow
> during type conversion, addition, subtraction, and multiplication.

I clearly cannot review such a huge patch, but I've noticed something
and would like to ask for clarification:

> +/**
> +  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;
> +}

Is our goal to

(a) catch overflows before the caller goes wrong due to them, or
(b) completely prevent undefined behavior from happening, even inside
SafeInt64Sub()?

The above implementation may be good for (a), but it's not correct for
(b). The

  SignedResult = Minuend - Subtrahend;

subtraction invokes undefined behavior if the result cannot be
represented [*]; the rest of the code cannot help.

Now if we say that such subtractions always occur according to the
"usual two's complement definition", on all architectures that edk2
targets, and we're sure that no compiler or analysis tool will flag --
or exploit -- the UB either, then the code is fine; meaning our choice
is (a).

But, if (b) is our goal, I would replace the current error condition with:

  (((Subtrahend > 0) && (Minuend < MIN_INT64 + Subtrahend)) ||
   ((Subtrahend < 0) && (Minuend > MAX_INT64 + Subtrahend)))

Justification:

* Subtrahend==0 can never cause overflow

* Subtrahend>0 can only cause overflow at the negative end, so check
  that: (Minuend - Subtrahend < MIN_INT64), mathematically speaking.
  In order to write that down in C, add Subtrahend (a positive value)
  to both sides, yielding (Minuend < MIN_INT64 + Subtrahend). Here,
  (MIN_INT64 + Subtrahend) will never go out of range, because
  Subtrahend is positive, and (MIN_INT64 + MAX_INT64) is representable.

* Subtrahend<0 can only cause overflow at the positive end, so check
  that: (Minuend - Subtrahend > MAX_INT64), mathematically speaking.
  In order to write that down in C, add Subtrahend (a negative value)
  to both sides, yielding (Minuend > MAX_INT64 + Subtrahend). Here,
  (MAX_INT64 + Subtrahend) will never go out of range, because
  Subtrahend is negative, and (MAX_INT64 + MIN_INT64) is representable.

(

[*] ISO C99 section 6.5 Expressions, p5: "If an exceptional condition
occurs during the evaluation of an expression (that is, if the result is
not mathematically defined or not in the range of representable values
for its type), the behavior is undefined."

Section 6.2.5 Types, p9 only exempts unsigned integers, "A computation
involving unsigned operands can never overflow, because a result that
cannot be represented by the resulting unsigned integer type is reduced
modulo the number that is one greater than the largest value that can be
represented by the resulting type."

Note that this is different from conversion, where the computation first
succeeds (= we have a value), and then the value is converted to a type
that causes truncation: section 6.3.1.3 Signed and unsigned integers,
p3: "Otherwise, the new type is signed and the value cannot be
represented in it; either the result is implementation-defined or an
implementation-defined signal is raised."

In the code above, the expression (Minuend - Subtrahend) can invoke
undefined behavior, there is no conversion (not even as part of the
assignment to SignedResult).

)

Thanks,
Laszlo


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance
  2018-02-08  0:32 ` Laszlo Ersek
@ 2018-02-08  0:45   ` Laszlo Ersek
  2018-02-13 12:23     ` Laszlo Ersek
  0 siblings, 1 reply; 16+ messages in thread
From: Laszlo Ersek @ 2018-02-08  0:45 UTC (permalink / raw)
  To: Kinney, Michael D, edk2-devel; +Cc: Liming Gao

On 02/08/18 01:32, Laszlo Ersek wrote:
> On 12/19/17 20:36, Kinney, Michael D wrote:
>> From: Sean Brogan <sean.brogan@microsoft.com>
>>
>> SafeIntLib provides helper functions to prevent integer overflow
>> during type conversion, addition, subtraction, and multiplication.
> 
> I clearly cannot review such a huge patch, but I've noticed something
> and would like to ask for clarification:
> 
>> +/**
>> +  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;
>> +}
> 
> Is our goal to
> 
> (a) catch overflows before the caller goes wrong due to them, or
> (b) completely prevent undefined behavior from happening, even inside
> SafeInt64Sub()?
> 
> The above implementation may be good for (a), but it's not correct for
> (b). The
> 
>   SignedResult = Minuend - Subtrahend;
> 
> subtraction invokes undefined behavior if the result cannot be
> represented [*]; the rest of the code cannot help.
> 
> Now if we say that such subtractions always occur according to the
> "usual two's complement definition", on all architectures that edk2
> targets, and we're sure that no compiler or analysis tool will flag --
> or exploit -- the UB either, then the code is fine; meaning our choice
> is (a).
> 
> But, if (b) is our goal, I would replace the current error condition with:
> 
>   (((Subtrahend > 0) && (Minuend < MIN_INT64 + Subtrahend)) ||
>    ((Subtrahend < 0) && (Minuend > MAX_INT64 + Subtrahend)))

To clarify, I wouldn't just replace the error condition. In addition to
that, I would remove the SignedResult helper variable (together with the
current subtraction), and calculate & assign

  *Result = Minuend - Subtrahend;

only after the error condition fails (i.e. the subtraction is safe).

Thanks,
Laszlo


> Justification:
> 
> * Subtrahend==0 can never cause overflow
> 
> * Subtrahend>0 can only cause overflow at the negative end, so check
>   that: (Minuend - Subtrahend < MIN_INT64), mathematically speaking.
>   In order to write that down in C, add Subtrahend (a positive value)
>   to both sides, yielding (Minuend < MIN_INT64 + Subtrahend). Here,
>   (MIN_INT64 + Subtrahend) will never go out of range, because
>   Subtrahend is positive, and (MIN_INT64 + MAX_INT64) is representable.
> 
> * Subtrahend<0 can only cause overflow at the positive end, so check
>   that: (Minuend - Subtrahend > MAX_INT64), mathematically speaking.
>   In order to write that down in C, add Subtrahend (a negative value)
>   to both sides, yielding (Minuend > MAX_INT64 + Subtrahend). Here,
>   (MAX_INT64 + Subtrahend) will never go out of range, because
>   Subtrahend is negative, and (MAX_INT64 + MIN_INT64) is representable.
> 
> (
> 
> [*] ISO C99 section 6.5 Expressions, p5: "If an exceptional condition
> occurs during the evaluation of an expression (that is, if the result is
> not mathematically defined or not in the range of representable values
> for its type), the behavior is undefined."
> 
> Section 6.2.5 Types, p9 only exempts unsigned integers, "A computation
> involving unsigned operands can never overflow, because a result that
> cannot be represented by the resulting unsigned integer type is reduced
> modulo the number that is one greater than the largest value that can be
> represented by the resulting type."
> 
> Note that this is different from conversion, where the computation first
> succeeds (= we have a value), and then the value is converted to a type
> that causes truncation: section 6.3.1.3 Signed and unsigned integers,
> p3: "Otherwise, the new type is signed and the value cannot be
> represented in it; either the result is implementation-defined or an
> implementation-defined signal is raised."
> 
> In the code above, the expression (Minuend - Subtrahend) can invoke
> undefined behavior, there is no conversion (not even as part of the
> assignment to SignedResult).
> 
> )
> 
> Thanks,
> Laszlo
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
> 



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance
  2018-02-08  0:45   ` Laszlo Ersek
@ 2018-02-13 12:23     ` Laszlo Ersek
  2018-02-13 16:17       ` Kinney, Michael D
  0 siblings, 1 reply; 16+ messages in thread
From: Laszlo Ersek @ 2018-02-13 12:23 UTC (permalink / raw)
  To: Kinney, Michael D, Sean Brogan; +Cc: edk2-devel, Liming Gao

Sean, Michael,

can you please follow up on this?

To clarify, I think this is a serious bug in SafeIntLib, dependent on
what we want to use this library for. As far as I understand, SafeIntLib
intends to centralize integer manipulation / arithmetic, so that client
code need not concern itself with overflow checking and such (on the C
expression level -- it still has to check return statuses, of course).
In other words, undefined behavior related to integer arithmetic is
supposed to be prevented in various modules by moving all such
operations into SafeIntLib, and letting client code use SafeIntLib APIs.

However, for this to work, SafeIntLib itself must be 100% free of
undefined behavior. And that's not the case (unless we define additional
guarantees -- on top of ISO C -- for edk2 target architectures). Should
I file a TianoCore BZ? Or is someone already (re)auditing the library?
Or else, is my concern unjustified? Please comment.

Thanks,
Laszlo

On 02/08/18 01:45, Laszlo Ersek wrote:
> On 02/08/18 01:32, Laszlo Ersek wrote:
>> On 12/19/17 20:36, Kinney, Michael D wrote:
>>> From: Sean Brogan <sean.brogan@microsoft.com>
>>>
>>> SafeIntLib provides helper functions to prevent integer overflow
>>> during type conversion, addition, subtraction, and multiplication.
>>
>> I clearly cannot review such a huge patch, but I've noticed something
>> and would like to ask for clarification:
>>
>>> +/**
>>> +  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;
>>> +}
>>
>> Is our goal to
>>
>> (a) catch overflows before the caller goes wrong due to them, or
>> (b) completely prevent undefined behavior from happening, even inside
>> SafeInt64Sub()?
>>
>> The above implementation may be good for (a), but it's not correct for
>> (b). The
>>
>>   SignedResult = Minuend - Subtrahend;
>>
>> subtraction invokes undefined behavior if the result cannot be
>> represented [*]; the rest of the code cannot help.
>>
>> Now if we say that such subtractions always occur according to the
>> "usual two's complement definition", on all architectures that edk2
>> targets, and we're sure that no compiler or analysis tool will flag --
>> or exploit -- the UB either, then the code is fine; meaning our choice
>> is (a).
>>
>> But, if (b) is our goal, I would replace the current error condition with:
>>
>>   (((Subtrahend > 0) && (Minuend < MIN_INT64 + Subtrahend)) ||
>>    ((Subtrahend < 0) && (Minuend > MAX_INT64 + Subtrahend)))
> 
> To clarify, I wouldn't just replace the error condition. In addition to
> that, I would remove the SignedResult helper variable (together with the
> current subtraction), and calculate & assign
> 
>   *Result = Minuend - Subtrahend;
> 
> only after the error condition fails (i.e. the subtraction is safe).
> 
> Thanks,
> Laszlo
> 
> 
>> Justification:
>>
>> * Subtrahend==0 can never cause overflow
>>
>> * Subtrahend>0 can only cause overflow at the negative end, so check
>>   that: (Minuend - Subtrahend < MIN_INT64), mathematically speaking.
>>   In order to write that down in C, add Subtrahend (a positive value)
>>   to both sides, yielding (Minuend < MIN_INT64 + Subtrahend). Here,
>>   (MIN_INT64 + Subtrahend) will never go out of range, because
>>   Subtrahend is positive, and (MIN_INT64 + MAX_INT64) is representable.
>>
>> * Subtrahend<0 can only cause overflow at the positive end, so check
>>   that: (Minuend - Subtrahend > MAX_INT64), mathematically speaking.
>>   In order to write that down in C, add Subtrahend (a negative value)
>>   to both sides, yielding (Minuend > MAX_INT64 + Subtrahend). Here,
>>   (MAX_INT64 + Subtrahend) will never go out of range, because
>>   Subtrahend is negative, and (MAX_INT64 + MIN_INT64) is representable.
>>
>> (
>>
>> [*] ISO C99 section 6.5 Expressions, p5: "If an exceptional condition
>> occurs during the evaluation of an expression (that is, if the result is
>> not mathematically defined or not in the range of representable values
>> for its type), the behavior is undefined."
>>
>> Section 6.2.5 Types, p9 only exempts unsigned integers, "A computation
>> involving unsigned operands can never overflow, because a result that
>> cannot be represented by the resulting unsigned integer type is reduced
>> modulo the number that is one greater than the largest value that can be
>> represented by the resulting type."
>>
>> Note that this is different from conversion, where the computation first
>> succeeds (= we have a value), and then the value is converted to a type
>> that causes truncation: section 6.3.1.3 Signed and unsigned integers,
>> p3: "Otherwise, the new type is signed and the value cannot be
>> represented in it; either the result is implementation-defined or an
>> implementation-defined signal is raised."
>>
>> In the code above, the expression (Minuend - Subtrahend) can invoke
>> undefined behavior, there is no conversion (not even as part of the
>> assignment to SignedResult).
>>
>> )
>>
>> Thanks,
>> Laszlo
>> _______________________________________________
>> edk2-devel mailing list
>> edk2-devel@lists.01.org
>> https://lists.01.org/mailman/listinfo/edk2-devel
>>
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
> 



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance
  2018-02-13 12:23     ` Laszlo Ersek
@ 2018-02-13 16:17       ` Kinney, Michael D
  2018-02-13 16:56         ` Bret Barkelew
  2018-02-13 17:18         ` Ard Biesheuvel
  0 siblings, 2 replies; 16+ messages in thread
From: Kinney, Michael D @ 2018-02-13 16:17 UTC (permalink / raw)
  To: Laszlo Ersek, Sean Brogan, Bret Barkelew
  Cc: edk2-devel@lists.01.org, Gao, Liming

+Bret

Mike

> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org]
> On Behalf Of Laszlo Ersek
> Sent: Tuesday, February 13, 2018 4:24 AM
> To: Kinney, Michael D <michael.d.kinney@intel.com>; Sean
> Brogan <sean.brogan@microsoft.com>
> Cc: edk2-devel@lists.01.org; Gao, Liming
> <liming.gao@intel.com>
> Subject: Re: [edk2] [Patch] MdePkg/BaseSafeIntLib: Add
> SafeIntLib class and instance
> 
> Sean, Michael,
> 
> can you please follow up on this?
> 
> To clarify, I think this is a serious bug in SafeIntLib,
> dependent on
> what we want to use this library for. As far as I
> understand, SafeIntLib
> intends to centralize integer manipulation / arithmetic,
> so that client
> code need not concern itself with overflow checking and
> such (on the C
> expression level -- it still has to check return
> statuses, of course).
> In other words, undefined behavior related to integer
> arithmetic is
> supposed to be prevented in various modules by moving all
> such
> operations into SafeIntLib, and letting client code use
> SafeIntLib APIs.
> 
> However, for this to work, SafeIntLib itself must be 100%
> free of
> undefined behavior. And that's not the case (unless we
> define additional
> guarantees -- on top of ISO C -- for edk2 target
> architectures). Should
> I file a TianoCore BZ? Or is someone already (re)auditing
> the library?
> Or else, is my concern unjustified? Please comment.
> 
> Thanks,
> Laszlo
> 
> On 02/08/18 01:45, Laszlo Ersek wrote:
> > On 02/08/18 01:32, Laszlo Ersek wrote:
> >> On 12/19/17 20:36, Kinney, Michael D wrote:
> >>> From: Sean Brogan <sean.brogan@microsoft.com>
> >>>
> >>> SafeIntLib provides helper functions to prevent
> integer overflow
> >>> during type conversion, addition, subtraction, and
> multiplication.
> >>
> >> I clearly cannot review such a huge patch, but I've
> noticed something
> >> and would like to ask for clarification:
> >>
> >>> +/**
> >>> +  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;
> >>> +}
> >>
> >> Is our goal to
> >>
> >> (a) catch overflows before the caller goes wrong due
> to them, or
> >> (b) completely prevent undefined behavior from
> happening, even inside
> >> SafeInt64Sub()?
> >>
> >> The above implementation may be good for (a), but it's
> not correct for
> >> (b). The
> >>
> >>   SignedResult = Minuend - Subtrahend;
> >>
> >> subtraction invokes undefined behavior if the result
> cannot be
> >> represented [*]; the rest of the code cannot help.
> >>
> >> Now if we say that such subtractions always occur
> according to the
> >> "usual two's complement definition", on all
> architectures that edk2
> >> targets, and we're sure that no compiler or analysis
> tool will flag --
> >> or exploit -- the UB either, then the code is fine;
> meaning our choice
> >> is (a).
> >>
> >> But, if (b) is our goal, I would replace the current
> error condition with:
> >>
> >>   (((Subtrahend > 0) && (Minuend < MIN_INT64 +
> Subtrahend)) ||
> >>    ((Subtrahend < 0) && (Minuend > MAX_INT64 +
> Subtrahend)))
> >
> > To clarify, I wouldn't just replace the error
> condition. In addition to
> > that, I would remove the SignedResult helper variable
> (together with the
> > current subtraction), and calculate & assign
> >
> >   *Result = Minuend - Subtrahend;
> >
> > only after the error condition fails (i.e. the
> subtraction is safe).
> >
> > Thanks,
> > Laszlo
> >
> >
> >> Justification:
> >>
> >> * Subtrahend==0 can never cause overflow
> >>
> >> * Subtrahend>0 can only cause overflow at the negative
> end, so check
> >>   that: (Minuend - Subtrahend < MIN_INT64),
> mathematically speaking.
> >>   In order to write that down in C, add Subtrahend (a
> positive value)
> >>   to both sides, yielding (Minuend < MIN_INT64 +
> Subtrahend). Here,
> >>   (MIN_INT64 + Subtrahend) will never go out of range,
> because
> >>   Subtrahend is positive, and (MIN_INT64 + MAX_INT64)
> is representable.
> >>
> >> * Subtrahend<0 can only cause overflow at the positive
> end, so check
> >>   that: (Minuend - Subtrahend > MAX_INT64),
> mathematically speaking.
> >>   In order to write that down in C, add Subtrahend (a
> negative value)
> >>   to both sides, yielding (Minuend > MAX_INT64 +
> Subtrahend). Here,
> >>   (MAX_INT64 + Subtrahend) will never go out of range,
> because
> >>   Subtrahend is negative, and (MAX_INT64 + MIN_INT64)
> is representable.
> >>
> >> (
> >>
> >> [*] ISO C99 section 6.5 Expressions, p5: "If an
> exceptional condition
> >> occurs during the evaluation of an expression (that
> is, if the result is
> >> not mathematically defined or not in the range of
> representable values
> >> for its type), the behavior is undefined."
> >>
> >> Section 6.2.5 Types, p9 only exempts unsigned
> integers, "A computation
> >> involving unsigned operands can never overflow,
> because a result that
> >> cannot be represented by the resulting unsigned
> integer type is reduced
> >> modulo the number that is one greater than the largest
> value that can be
> >> represented by the resulting type."
> >>
> >> Note that this is different from conversion, where the
> computation first
> >> succeeds (= we have a value), and then the value is
> converted to a type
> >> that causes truncation: section 6.3.1.3 Signed and
> unsigned integers,
> >> p3: "Otherwise, the new type is signed and the value
> cannot be
> >> represented in it; either the result is
> implementation-defined or an
> >> implementation-defined signal is raised."
> >>
> >> In the code above, the expression (Minuend -
> Subtrahend) can invoke
> >> undefined behavior, there is no conversion (not even
> as part of the
> >> assignment to SignedResult).
> >>
> >> )
> >>
> >> Thanks,
> >> Laszlo
> >> _______________________________________________
> >> edk2-devel mailing list
> >> edk2-devel@lists.01.org
> >> https://lists.01.org/mailman/listinfo/edk2-devel
> >>
> >
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org
> > https://lists.01.org/mailman/listinfo/edk2-devel
> >
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance
  2018-02-13 16:17       ` Kinney, Michael D
@ 2018-02-13 16:56         ` Bret Barkelew
  2018-02-13 17:15           ` Andrew Fish
  2018-02-13 17:29           ` Laszlo Ersek
  2018-02-13 17:18         ` Ard Biesheuvel
  1 sibling, 2 replies; 16+ messages in thread
From: Bret Barkelew @ 2018-02-13 16:56 UTC (permalink / raw)
  To: Kinney, Michael D, Laszlo Ersek, Sean Brogan
  Cc: edk2-devel@lists.01.org, Gao, Liming

In response to the original question, I would content that our goal should be "a". We should be allowing universal detection of errors without the caller having to carry this detection code itself.

The analog would be the safe string functions: if a buffer overflow occurs, they don't find a way to "fix" the operation, but they faithfully report an error.

As such, I believe from my review that these functions work as intended.

- Bret
________________________________
From: Kinney, Michael D <michael.d.kinney@intel.com>
Sent: Tuesday, February 13, 2018 8:17:48 AM
To: Laszlo Ersek; Sean Brogan; Bret Barkelew
Cc: edk2-devel@lists.01.org; Gao, Liming
Subject: RE: [edk2] [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance

+Bret

Mike

> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org]
> On Behalf Of Laszlo Ersek
> Sent: Tuesday, February 13, 2018 4:24 AM
> To: Kinney, Michael D <michael.d.kinney@intel.com>; Sean
> Brogan <sean.brogan@microsoft.com>
> Cc: edk2-devel@lists.01.org; Gao, Liming
> <liming.gao@intel.com>
> Subject: Re: [edk2] [Patch] MdePkg/BaseSafeIntLib: Add
> SafeIntLib class and instance
>
> Sean, Michael,
>
> can you please follow up on this?
>
> To clarify, I think this is a serious bug in SafeIntLib,
> dependent on
> what we want to use this library for. As far as I
> understand, SafeIntLib
> intends to centralize integer manipulation / arithmetic,
> so that client
> code need not concern itself with overflow checking and
> such (on the C
> expression level -- it still has to check return
> statuses, of course).
> In other words, undefined behavior related to integer
> arithmetic is
> supposed to be prevented in various modules by moving all
> such
> operations into SafeIntLib, and letting client code use
> SafeIntLib APIs.
>
> However, for this to work, SafeIntLib itself must be 100%
> free of
> undefined behavior. And that's not the case (unless we
> define additional
> guarantees -- on top of ISO C -- for edk2 target
> architectures). Should
> I file a TianoCore BZ? Or is someone already (re)auditing
> the library?
> Or else, is my concern unjustified? Please comment.
>
> Thanks,
> Laszlo
>
> On 02/08/18 01:45, Laszlo Ersek wrote:
> > On 02/08/18 01:32, Laszlo Ersek wrote:
> >> On 12/19/17 20:36, Kinney, Michael D wrote:
> >>> From: Sean Brogan <sean.brogan@microsoft.com>
> >>>
> >>> SafeIntLib provides helper functions to prevent
> integer overflow
> >>> during type conversion, addition, subtraction, and
> multiplication.
> >>
> >> I clearly cannot review such a huge patch, but I've
> noticed something
> >> and would like to ask for clarification:
> >>
> >>> +/**
> >>> +  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;
> >>> +}
> >>
> >> Is our goal to
> >>
> >> (a) catch overflows before the caller goes wrong due
> to them, or
> >> (b) completely prevent undefined behavior from
> happening, even inside
> >> SafeInt64Sub()?
> >>
> >> The above implementation may be good for (a), but it's
> not correct for
> >> (b). The
> >>
> >>   SignedResult = Minuend - Subtrahend;
> >>
> >> subtraction invokes undefined behavior if the result
> cannot be
> >> represented [*]; the rest of the code cannot help.
> >>
> >> Now if we say that such subtractions always occur
> according to the
> >> "usual two's complement definition", on all
> architectures that edk2
> >> targets, and we're sure that no compiler or analysis
> tool will flag --
> >> or exploit -- the UB either, then the code is fine;
> meaning our choice
> >> is (a).
> >>
> >> But, if (b) is our goal, I would replace the current
> error condition with:
> >>
> >>   (((Subtrahend > 0) && (Minuend < MIN_INT64 +
> Subtrahend)) ||
> >>    ((Subtrahend < 0) && (Minuend > MAX_INT64 +
> Subtrahend)))
> >
> > To clarify, I wouldn't just replace the error
> condition. In addition to
> > that, I would remove the SignedResult helper variable
> (together with the
> > current subtraction), and calculate & assign
> >
> >   *Result = Minuend - Subtrahend;
> >
> > only after the error condition fails (i.e. the
> subtraction is safe).
> >
> > Thanks,
> > Laszlo
> >
> >
> >> Justification:
> >>
> >> * Subtrahend==0 can never cause overflow
> >>
> >> * Subtrahend>0 can only cause overflow at the negative
> end, so check
> >>   that: (Minuend - Subtrahend < MIN_INT64),
> mathematically speaking.
> >>   In order to write that down in C, add Subtrahend (a
> positive value)
> >>   to both sides, yielding (Minuend < MIN_INT64 +
> Subtrahend). Here,
> >>   (MIN_INT64 + Subtrahend) will never go out of range,
> because
> >>   Subtrahend is positive, and (MIN_INT64 + MAX_INT64)
> is representable.
> >>
> >> * Subtrahend<0 can only cause overflow at the positive
> end, so check
> >>   that: (Minuend - Subtrahend > MAX_INT64),
> mathematically speaking.
> >>   In order to write that down in C, add Subtrahend (a
> negative value)
> >>   to both sides, yielding (Minuend > MAX_INT64 +
> Subtrahend). Here,
> >>   (MAX_INT64 + Subtrahend) will never go out of range,
> because
> >>   Subtrahend is negative, and (MAX_INT64 + MIN_INT64)
> is representable.
> >>
> >> (
> >>
> >> [*] ISO C99 section 6.5 Expressions, p5: "If an
> exceptional condition
> >> occurs during the evaluation of an expression (that
> is, if the result is
> >> not mathematically defined or not in the range of
> representable values
> >> for its type), the behavior is undefined."
> >>
> >> Section 6.2.5 Types, p9 only exempts unsigned
> integers, "A computation
> >> involving unsigned operands can never overflow,
> because a result that
> >> cannot be represented by the resulting unsigned
> integer type is reduced
> >> modulo the number that is one greater than the largest
> value that can be
> >> represented by the resulting type."
> >>
> >> Note that this is different from conversion, where the
> computation first
> >> succeeds (= we have a value), and then the value is
> converted to a type
> >> that causes truncation: section 6.3.1.3 Signed and
> unsigned integers,
> >> p3: "Otherwise, the new type is signed and the value
> cannot be
> >> represented in it; either the result is
> implementation-defined or an
> >> implementation-defined signal is raised."
> >>
> >> In the code above, the expression (Minuend -
> Subtrahend) can invoke
> >> undefined behavior, there is no conversion (not even
> as part of the
> >> assignment to SignedResult).
> >>
> >> )
> >>
> >> Thanks,
> >> Laszlo
> >> _______________________________________________
> >> edk2-devel mailing list
> >> edk2-devel@lists.01.org
> >> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.01.org%2Fmailman%2Flistinfo%2Fedk2-devel&data=04%7C01%7CBret.Barkelew%40microsoft.com%7C87f15d7947fe45fee17a08d572fd542d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636541354724483642%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwifQ%3D%3D%7C-1&sdata=rFfax%2BkpyDxZt9UPmIT9tdBFC1KOeq3Xhfudm00XcC0%3D&reserved=0
> >>
> >
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org
> > https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.01.org%2Fmailman%2Flistinfo%2Fedk2-devel&data=04%7C01%7CBret.Barkelew%40microsoft.com%7C87f15d7947fe45fee17a08d572fd542d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636541354724483642%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwifQ%3D%3D%7C-1&sdata=rFfax%2BkpyDxZt9UPmIT9tdBFC1KOeq3Xhfudm00XcC0%3D&reserved=0
> >
>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.01.org%2Fmailman%2Flistinfo%2Fedk2-devel&data=04%7C01%7CBret.Barkelew%40microsoft.com%7C87f15d7947fe45fee17a08d572fd542d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636541354724483642%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwifQ%3D%3D%7C-1&sdata=rFfax%2BkpyDxZt9UPmIT9tdBFC1KOeq3Xhfudm00XcC0%3D&reserved=0


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance
  2018-02-13 16:56         ` Bret Barkelew
@ 2018-02-13 17:15           ` Andrew Fish
  2018-02-13 17:55             ` Laszlo Ersek
  2018-02-13 17:29           ` Laszlo Ersek
  1 sibling, 1 reply; 16+ messages in thread
From: Andrew Fish @ 2018-02-13 17:15 UTC (permalink / raw)
  To: Bret Barkelew
  Cc: Mike Kinney, Laszlo Ersek, Sean Brogan, edk2-devel@lists.01.org,
	Gao, Liming



> On Feb 13, 2018, at 8:56 AM, Bret Barkelew <Bret.Barkelew@microsoft.com> wrote:
> 
> In response to the original question, I would content that our goal should be "a". We should be allowing universal detection of errors without the caller having to carry this detection code itself.
> 
> The analog would be the safe string functions: if a buffer overflow occurs, they don't find a way to "fix" the operation, but they faithfully report an error.
> 
> As such, I believe from my review that these functions work as intended.
> 

Bret,

I think Lazlo's point is that undefined behavior[1]  can cause the math function to break in the future and that we have to be very pedantic in how it is coded. Per the C standard it is legal for the compiler to optimized away undefined behavior[2], and clang is very aggressive about warning on undefined behavior and then updating the optimizer to remove the code in a future release. For example the BaseTool compression code broke with Xcode 9 recently due to the presence of an illegal 32-bit shift that was only hit when the optimizer inlined the function. While the compiler tries to emit warnings, or at least traps, for undefined behavior what we have seen with the Link Time Optimization is the code can just get removed. 

[1] - Kind of clangs point of view on undefined behavior in C: http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html <http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html>
[2] - Example of undefined behavior in clang that emits a trap. Dereferencing NULL is undefined behavior in C so clang emits a trap, and optimizes way the code after the trap. 

~/work/Compiler>cat undefined.c

int
main ()
{
  int *Yikes = 0;

  *Yikes = 1;
  return 0;
}

~/work/Compiler>clang -S -Os undefined.c
~/work/Compiler>cat undefined.S
	.section	__TEXT,__text,regular,pure_instructions
	.macosx_version_min 10, 12
	.globl	_main
_main:                                  ## @main
	.cfi_startproc
## BB#0:
	pushq	%rbp
Lcfi0:
	.cfi_def_cfa_offset 16
Lcfi1:
	.cfi_offset %rbp, -16
	movq	%rsp, %rbp
Lcfi2:
	.cfi_def_cfa_register %rbp
	ud2
	.cfi_endproc


.subsections_via_symbols

Thanks,

Andrew Fish

> - Bret
> ________________________________
> From: Kinney, Michael D <michael.d.kinney@intel.com <mailto:michael.d.kinney@intel.com>>
> Sent: Tuesday, February 13, 2018 8:17:48 AM
> To: Laszlo Ersek; Sean Brogan; Bret Barkelew
> Cc: edk2-devel@lists.01.org <mailto:edk2-devel@lists.01.org>; Gao, Liming
> Subject: RE: [edk2] [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance
> 
> +Bret
> 
> Mike
> 
>> -----Original Message-----
>> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org]
>> On Behalf Of Laszlo Ersek
>> Sent: Tuesday, February 13, 2018 4:24 AM
>> To: Kinney, Michael D <michael.d.kinney@intel.com>; Sean
>> Brogan <sean.brogan@microsoft.com>
>> Cc: edk2-devel@lists.01.org; Gao, Liming
>> <liming.gao@intel.com>
>> Subject: Re: [edk2] [Patch] MdePkg/BaseSafeIntLib: Add
>> SafeIntLib class and instance
>> 
>> Sean, Michael,
>> 
>> can you please follow up on this?
>> 
>> To clarify, I think this is a serious bug in SafeIntLib,
>> dependent on
>> what we want to use this library for. As far as I
>> understand, SafeIntLib
>> intends to centralize integer manipulation / arithmetic,
>> so that client
>> code need not concern itself with overflow checking and
>> such (on the C
>> expression level -- it still has to check return
>> statuses, of course).
>> In other words, undefined behavior related to integer
>> arithmetic is
>> supposed to be prevented in various modules by moving all
>> such
>> operations into SafeIntLib, and letting client code use
>> SafeIntLib APIs.
>> 
>> However, for this to work, SafeIntLib itself must be 100%
>> free of
>> undefined behavior. And that's not the case (unless we
>> define additional
>> guarantees -- on top of ISO C -- for edk2 target
>> architectures). Should
>> I file a TianoCore BZ? Or is someone already (re)auditing
>> the library?
>> Or else, is my concern unjustified? Please comment.
>> 
>> Thanks,
>> Laszlo
>> 
>> On 02/08/18 01:45, Laszlo Ersek wrote:
>>> On 02/08/18 01:32, Laszlo Ersek wrote:
>>>> On 12/19/17 20:36, Kinney, Michael D wrote:
>>>>> From: Sean Brogan <sean.brogan@microsoft.com>
>>>>> 
>>>>> SafeIntLib provides helper functions to prevent
>> integer overflow
>>>>> during type conversion, addition, subtraction, and
>> multiplication.
>>>> 
>>>> I clearly cannot review such a huge patch, but I've
>> noticed something
>>>> and would like to ask for clarification:
>>>> 
>>>>> +/**
>>>>> +  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;
>>>>> +}
>>>> 
>>>> Is our goal to
>>>> 
>>>> (a) catch overflows before the caller goes wrong due
>> to them, or
>>>> (b) completely prevent undefined behavior from
>> happening, even inside
>>>> SafeInt64Sub()?
>>>> 
>>>> The above implementation may be good for (a), but it's
>> not correct for
>>>> (b). The
>>>> 
>>>>  SignedResult = Minuend - Subtrahend;
>>>> 
>>>> subtraction invokes undefined behavior if the result
>> cannot be
>>>> represented [*]; the rest of the code cannot help.
>>>> 
>>>> Now if we say that such subtractions always occur
>> according to the
>>>> "usual two's complement definition", on all
>> architectures that edk2
>>>> targets, and we're sure that no compiler or analysis
>> tool will flag --
>>>> or exploit -- the UB either, then the code is fine;
>> meaning our choice
>>>> is (a).
>>>> 
>>>> But, if (b) is our goal, I would replace the current
>> error condition with:
>>>> 
>>>>  (((Subtrahend > 0) && (Minuend < MIN_INT64 +
>> Subtrahend)) ||
>>>>   ((Subtrahend < 0) && (Minuend > MAX_INT64 +
>> Subtrahend)))
>>> 
>>> To clarify, I wouldn't just replace the error
>> condition. In addition to
>>> that, I would remove the SignedResult helper variable
>> (together with the
>>> current subtraction), and calculate & assign
>>> 
>>>  *Result = Minuend - Subtrahend;
>>> 
>>> only after the error condition fails (i.e. the
>> subtraction is safe).
>>> 
>>> Thanks,
>>> Laszlo
>>> 
>>> 
>>>> Justification:
>>>> 
>>>> * Subtrahend==0 can never cause overflow
>>>> 
>>>> * Subtrahend>0 can only cause overflow at the negative
>> end, so check
>>>>  that: (Minuend - Subtrahend < MIN_INT64),
>> mathematically speaking.
>>>>  In order to write that down in C, add Subtrahend (a
>> positive value)
>>>>  to both sides, yielding (Minuend < MIN_INT64 +
>> Subtrahend). Here,
>>>>  (MIN_INT64 + Subtrahend) will never go out of range,
>> because
>>>>  Subtrahend is positive, and (MIN_INT64 + MAX_INT64)
>> is representable.
>>>> 
>>>> * Subtrahend<0 can only cause overflow at the positive
>> end, so check
>>>>  that: (Minuend - Subtrahend > MAX_INT64),
>> mathematically speaking.
>>>>  In order to write that down in C, add Subtrahend (a
>> negative value)
>>>>  to both sides, yielding (Minuend > MAX_INT64 +
>> Subtrahend). Here,
>>>>  (MAX_INT64 + Subtrahend) will never go out of range,
>> because
>>>>  Subtrahend is negative, and (MAX_INT64 + MIN_INT64)
>> is representable.
>>>> 
>>>> (
>>>> 
>>>> [*] ISO C99 section 6.5 Expressions, p5: "If an
>> exceptional condition
>>>> occurs during the evaluation of an expression (that
>> is, if the result is
>>>> not mathematically defined or not in the range of
>> representable values
>>>> for its type), the behavior is undefined."
>>>> 
>>>> Section 6.2.5 Types, p9 only exempts unsigned
>> integers, "A computation
>>>> involving unsigned operands can never overflow,
>> because a result that
>>>> cannot be represented by the resulting unsigned
>> integer type is reduced
>>>> modulo the number that is one greater than the largest
>> value that can be
>>>> represented by the resulting type."
>>>> 
>>>> Note that this is different from conversion, where the
>> computation first
>>>> succeeds (= we have a value), and then the value is
>> converted to a type
>>>> that causes truncation: section 6.3.1.3 Signed and
>> unsigned integers,
>>>> p3: "Otherwise, the new type is signed and the value
>> cannot be
>>>> represented in it; either the result is
>> implementation-defined or an
>>>> implementation-defined signal is raised."
>>>> 
>>>> In the code above, the expression (Minuend -
>> Subtrahend) can invoke
>>>> undefined behavior, there is no conversion (not even
>> as part of the
>>>> assignment to SignedResult).
>>>> 
>>>> )
>>>> 
>>>> Thanks,
>>>> Laszlo
>>>> _______________________________________________
>>>> edk2-devel mailing list
>>>> edk2-devel@lists.01.org
>>>> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.01.org%2Fmailman%2Flistinfo%2Fedk2-devel&data=04%7C01%7CBret.Barkelew%40microsoft.com%7C87f15d7947fe45fee17a08d572fd542d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636541354724483642%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwifQ%3D%3D%7C-1&sdata=rFfax%2BkpyDxZt9UPmIT9tdBFC1KOeq3Xhfudm00XcC0%3D&reserved=0 <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.01.org%2Fmailman%2Flistinfo%2Fedk2-devel&data=04%7C01%7CBret.Barkelew%40microsoft.com%7C87f15d7947fe45fee17a08d572fd542d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636541354724483642%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwifQ%3D%3D%7C-1&sdata=rFfax%2BkpyDxZt9UPmIT9tdBFC1KOeq3Xhfudm00XcC0%3D&reserved=0>
>>>> 
>>> 
>>> _______________________________________________
>>> edk2-devel mailing list
>>> edk2-devel@lists.01.org <mailto:edk2-devel@lists.01.org>
>>> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.01.org%2Fmailman%2Flistinfo%2Fedk2-devel&data=04%7C01%7CBret.Barkelew%40microsoft.com%7C87f15d7947fe45fee17a08d572fd542d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636541354724483642%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwifQ%3D%3D%7C-1&sdata=rFfax%2BkpyDxZt9UPmIT9tdBFC1KOeq3Xhfudm00XcC0%3D&reserved=0 <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.01.org%2Fmailman%2Flistinfo%2Fedk2-devel&data=04%7C01%7CBret.Barkelew%40microsoft.com%7C87f15d7947fe45fee17a08d572fd542d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636541354724483642%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwifQ%3D%3D%7C-1&sdata=rFfax%2BkpyDxZt9UPmIT9tdBFC1KOeq3Xhfudm00XcC0%3D&reserved=0>
>>> 
>> 
>> _______________________________________________
>> edk2-devel mailing list
>> edk2-devel@lists.01.org <mailto:edk2-devel@lists.01.org>
>> https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.01.org%2Fmailman%2Flistinfo%2Fedk2-devel&data=04%7C01%7CBret.Barkelew%40microsoft.com%7C87f15d7947fe45fee17a08d572fd542d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636541354724483642%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwifQ%3D%3D%7C-1&sdata=rFfax%2BkpyDxZt9UPmIT9tdBFC1KOeq3Xhfudm00XcC0%3D&reserved=0 <https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.01.org%2Fmailman%2Flistinfo%2Fedk2-devel&data=04%7C01%7CBret.Barkelew%40microsoft.com%7C87f15d7947fe45fee17a08d572fd542d%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636541354724483642%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwifQ%3D%3D%7C-1&sdata=rFfax%2BkpyDxZt9UPmIT9tdBFC1KOeq3Xhfudm00XcC0%3D&reserved=0>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org <mailto:edk2-devel@lists.01.org>
> https://lists.01.org/mailman/listinfo/edk2-devel <https://lists.01.org/mailman/listinfo/edk2-devel>


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance
  2018-02-13 16:17       ` Kinney, Michael D
  2018-02-13 16:56         ` Bret Barkelew
@ 2018-02-13 17:18         ` Ard Biesheuvel
  2018-02-13 17:51           ` Laszlo Ersek
  1 sibling, 1 reply; 16+ messages in thread
From: Ard Biesheuvel @ 2018-02-13 17:18 UTC (permalink / raw)
  To: Kinney, Michael D
  Cc: Laszlo Ersek, Sean Brogan, Bret Barkelew, edk2-devel@lists.01.org,
	Gao, Liming

On 13 February 2018 at 16:17, Kinney, Michael D
<michael.d.kinney@intel.com> wrote:
> +Bret
>
> Mike
>

Why has this patch been submitted if there are unanswered questions of
such a fundamental nature?
Could someone please revert it until there is agreement about its
inclusion (and in which form)?


>> -----Original Message-----
>> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org]
>> On Behalf Of Laszlo Ersek
>> Sent: Tuesday, February 13, 2018 4:24 AM
>> To: Kinney, Michael D <michael.d.kinney@intel.com>; Sean
>> Brogan <sean.brogan@microsoft.com>
>> Cc: edk2-devel@lists.01.org; Gao, Liming
>> <liming.gao@intel.com>
>> Subject: Re: [edk2] [Patch] MdePkg/BaseSafeIntLib: Add
>> SafeIntLib class and instance
>>
>> Sean, Michael,
>>
>> can you please follow up on this?
>>
>> To clarify, I think this is a serious bug in SafeIntLib,
>> dependent on
>> what we want to use this library for. As far as I
>> understand, SafeIntLib
>> intends to centralize integer manipulation / arithmetic,
>> so that client
>> code need not concern itself with overflow checking and
>> such (on the C
>> expression level -- it still has to check return
>> statuses, of course).
>> In other words, undefined behavior related to integer
>> arithmetic is
>> supposed to be prevented in various modules by moving all
>> such
>> operations into SafeIntLib, and letting client code use
>> SafeIntLib APIs.
>>
>> However, for this to work, SafeIntLib itself must be 100%
>> free of
>> undefined behavior. And that's not the case (unless we
>> define additional
>> guarantees -- on top of ISO C -- for edk2 target
>> architectures). Should
>> I file a TianoCore BZ? Or is someone already (re)auditing
>> the library?
>> Or else, is my concern unjustified? Please comment.
>>
>> Thanks,
>> Laszlo
>>
>> On 02/08/18 01:45, Laszlo Ersek wrote:
>> > On 02/08/18 01:32, Laszlo Ersek wrote:
>> >> On 12/19/17 20:36, Kinney, Michael D wrote:
>> >>> From: Sean Brogan <sean.brogan@microsoft.com>
>> >>>
>> >>> SafeIntLib provides helper functions to prevent
>> integer overflow
>> >>> during type conversion, addition, subtraction, and
>> multiplication.
>> >>
>> >> I clearly cannot review such a huge patch, but I've
>> noticed something
>> >> and would like to ask for clarification:
>> >>
>> >>> +/**
>> >>> +  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;
>> >>> +}
>> >>
>> >> Is our goal to
>> >>
>> >> (a) catch overflows before the caller goes wrong due
>> to them, or
>> >> (b) completely prevent undefined behavior from
>> happening, even inside
>> >> SafeInt64Sub()?
>> >>
>> >> The above implementation may be good for (a), but it's
>> not correct for
>> >> (b). The
>> >>
>> >>   SignedResult = Minuend - Subtrahend;
>> >>
>> >> subtraction invokes undefined behavior if the result
>> cannot be
>> >> represented [*]; the rest of the code cannot help.
>> >>
>> >> Now if we say that such subtractions always occur
>> according to the
>> >> "usual two's complement definition", on all
>> architectures that edk2
>> >> targets, and we're sure that no compiler or analysis
>> tool will flag --
>> >> or exploit -- the UB either, then the code is fine;
>> meaning our choice
>> >> is (a).
>> >>
>> >> But, if (b) is our goal, I would replace the current
>> error condition with:
>> >>
>> >>   (((Subtrahend > 0) && (Minuend < MIN_INT64 +
>> Subtrahend)) ||
>> >>    ((Subtrahend < 0) && (Minuend > MAX_INT64 +
>> Subtrahend)))
>> >
>> > To clarify, I wouldn't just replace the error
>> condition. In addition to
>> > that, I would remove the SignedResult helper variable
>> (together with the
>> > current subtraction), and calculate & assign
>> >
>> >   *Result = Minuend - Subtrahend;
>> >
>> > only after the error condition fails (i.e. the
>> subtraction is safe).
>> >
>> > Thanks,
>> > Laszlo
>> >
>> >
>> >> Justification:
>> >>
>> >> * Subtrahend==0 can never cause overflow
>> >>
>> >> * Subtrahend>0 can only cause overflow at the negative
>> end, so check
>> >>   that: (Minuend - Subtrahend < MIN_INT64),
>> mathematically speaking.
>> >>   In order to write that down in C, add Subtrahend (a
>> positive value)
>> >>   to both sides, yielding (Minuend < MIN_INT64 +
>> Subtrahend). Here,
>> >>   (MIN_INT64 + Subtrahend) will never go out of range,
>> because
>> >>   Subtrahend is positive, and (MIN_INT64 + MAX_INT64)
>> is representable.
>> >>
>> >> * Subtrahend<0 can only cause overflow at the positive
>> end, so check
>> >>   that: (Minuend - Subtrahend > MAX_INT64),
>> mathematically speaking.
>> >>   In order to write that down in C, add Subtrahend (a
>> negative value)
>> >>   to both sides, yielding (Minuend > MAX_INT64 +
>> Subtrahend). Here,
>> >>   (MAX_INT64 + Subtrahend) will never go out of range,
>> because
>> >>   Subtrahend is negative, and (MAX_INT64 + MIN_INT64)
>> is representable.
>> >>
>> >> (
>> >>
>> >> [*] ISO C99 section 6.5 Expressions, p5: "If an
>> exceptional condition
>> >> occurs during the evaluation of an expression (that
>> is, if the result is
>> >> not mathematically defined or not in the range of
>> representable values
>> >> for its type), the behavior is undefined."
>> >>
>> >> Section 6.2.5 Types, p9 only exempts unsigned
>> integers, "A computation
>> >> involving unsigned operands can never overflow,
>> because a result that
>> >> cannot be represented by the resulting unsigned
>> integer type is reduced
>> >> modulo the number that is one greater than the largest
>> value that can be
>> >> represented by the resulting type."
>> >>
>> >> Note that this is different from conversion, where the
>> computation first
>> >> succeeds (= we have a value), and then the value is
>> converted to a type
>> >> that causes truncation: section 6.3.1.3 Signed and
>> unsigned integers,
>> >> p3: "Otherwise, the new type is signed and the value
>> cannot be
>> >> represented in it; either the result is
>> implementation-defined or an
>> >> implementation-defined signal is raised."
>> >>
>> >> In the code above, the expression (Minuend -
>> Subtrahend) can invoke
>> >> undefined behavior, there is no conversion (not even
>> as part of the
>> >> assignment to SignedResult).
>> >>
>> >> )
>> >>
>> >> Thanks,
>> >> Laszlo
>> >> _______________________________________________
>> >> edk2-devel mailing list
>> >> edk2-devel@lists.01.org
>> >> https://lists.01.org/mailman/listinfo/edk2-devel
>> >>
>> >
>> > _______________________________________________
>> > edk2-devel mailing list
>> > edk2-devel@lists.01.org
>> > https://lists.01.org/mailman/listinfo/edk2-devel
>> >
>>
>> _______________________________________________
>> edk2-devel mailing list
>> edk2-devel@lists.01.org
>> https://lists.01.org/mailman/listinfo/edk2-devel
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance
  2018-02-13 16:56         ` Bret Barkelew
  2018-02-13 17:15           ` Andrew Fish
@ 2018-02-13 17:29           ` Laszlo Ersek
  2018-02-13 18:19             ` Bret Barkelew
  1 sibling, 1 reply; 16+ messages in thread
From: Laszlo Ersek @ 2018-02-13 17:29 UTC (permalink / raw)
  To: Bret Barkelew, Kinney, Michael D, Sean Brogan
  Cc: edk2-devel@lists.01.org, Gao, Liming

On 02/13/18 17:56, Bret Barkelew wrote:
> In response to the original question, I would content that our goal
> should be "a". We should be allowing universal detection of errors
> without the caller having to carry this detection code itself.

OK.

The question is how the detection is implemented internally. Is that
implementation (in edk2) allowed to rely on behavior that the ISO C
standard leaves undefined, and -- consequently -- compilers might
exploit for code generation?

> The analog would be the safe string functions: if a buffer overflow
> occurs, they don't find a way to "fix" the operation, but they
> faithfully report an error.

Precisely.

Correspondingly, translated to the safe string functions, my question
becomes:

Is the implementation of the safe string functions allowed to employ
buffer overflow internally, and detect the overflow after the fact?

> As such, I believe from my review that these functions work as
> intended.

Please let me quote the function again, from
"MdePkg/Library/BaseSafeIntLib/SafeIntLib.c":

  3831  RETURN_STATUS
  3832  EFIAPI
  3833  SafeInt64Sub (
  3834    IN  INT64  Minuend,
  3835    IN  INT64  Subtrahend,
  3836    OUT INT64  *Result
  3837    )
  3838  {
  3839    RETURN_STATUS  Status;
  3840    INT64          SignedResult;
  3841
  3842    if (Result == NULL) {
  3843      return RETURN_INVALID_PARAMETER;
  3844    }
  3845
  3846    SignedResult = Minuend - Subtrahend;
  3847
  3848    //
  3849    // Subtracting a positive number from a positive number never overflows.
  3850    // Subtracting a negative number from a negative number never overflows.
  3851    // If you subtract a negative number from a positive number, you expect a positive result.
  3852    // If you subtract a positive number from a negative number, you expect a negative result.
  3853    // Overflow if inputs vary in sign and the output does not have the same sign as the first input.
  3854    //
  3855    if (((Minuend < 0) != (Subtrahend < 0)) &&
  3856        ((Minuend < 0) != (SignedResult < 0))) {
  3857      *Result = INT64_ERROR;
  3858      Status = RETURN_BUFFER_TOO_SMALL;
  3859    } else {
  3860      *Result = SignedResult;
  3861      Status = RETURN_SUCCESS;
  3862    }
  3863
  3864    return Status;
  3865  }

On line 3846, integer overflow is possible. If that happens, not only is
the resultant value of "SignedResult" undefined, but the behavior of the
rest of the function is undefined, according to ISO C.

In other words, just because we move the checking into a library
function, we cannot check *after the fact*. The subtraction on line 3846
can invoke undefined behavior *first*, and we check only afterwards,
starting on line 3855.

Here's an analogy. Various C compilers regularly equate "undefined
behavior" with "never happens" (which is a valid interpretation of the
ISO C standard for the compiler to make). For example, given the code

  int f(int *x)
  {
    *x = 3;
    if (x == NULL) {
      return 1;
    }
    return 0;
}

the compiler may compile f() to unconditionally return 0, such as:

  int f(int *x)
  {
    *x = 3;
    return 0;
  }

Because, the (x == NULL) branch would depend on undefined behavior
invoked by the assignment to *x. Given that the (*x = 3) assignment is
undefined for (x==NULL), according to ISO C, the subsequent (x == NULL)
check can be taken as constant false, and eliminated.

Similarly, a sufficiently smart compiler may assume that the subtraction
on line 3846 will never overflow. (Because, such an overflow would be
undefined behavior.) Consequently, it may deduce that the overflow
checks, *after the fact*, evaluate to constant false, and can be
eliminated. It might compile the function as in:

  {
    RETURN_STATUS  Status;
    INT64          SignedResult;

    if (Result == NULL) {
      return RETURN_INVALID_PARAMETER;
    }

    SignedResult = Minuend - Subtrahend;

    *Result = SignedResult;
    Status = RETURN_SUCCESS;

    return Status;
  }

I apoligize if I'm unclear; I really don't know how to put it better.
The subtraction on line 3846 runs the risk of undefined behavior, and
the checks starting on line 3855 are too late.

Thanks
Laszlo


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance
  2018-02-13 17:18         ` Ard Biesheuvel
@ 2018-02-13 17:51           ` Laszlo Ersek
  2018-02-13 17:55             ` Ard Biesheuvel
  2018-02-13 18:03             ` Laszlo Ersek
  0 siblings, 2 replies; 16+ messages in thread
From: Laszlo Ersek @ 2018-02-13 17:51 UTC (permalink / raw)
  To: Ard Biesheuvel, Kinney, Michael D
  Cc: Sean Brogan, Bret Barkelew, edk2-devel@lists.01.org, Gao, Liming

On 02/13/18 18:18, Ard Biesheuvel wrote:
> On 13 February 2018 at 16:17, Kinney, Michael D
> <michael.d.kinney@intel.com> wrote:
>> +Bret
>>
>> Mike
>>
> 
> Why has this patch been submitted if there are unanswered questions of
> such a fundamental nature?
> Could someone please revert it until there is agreement about its
> inclusion (and in which form)?

I think your question is "why has this patch been *committed* / pushed
if such questions remain"; is that correct?

The patch was correctly submitted to edk2-devel for review back in
December 2017. At that time I quickly glanced at the diffstat, and I
didn't even start reviewing the patch -- "15 files changed, 8915
insertions(+), 9 deletions(-)". For me to review such a large amount of
code in detail, it would have to be split into tens of patches, and I'd
likely have to work on the review intensely for a week or more. So, I
asumed that SafeIntLib had been carefully reviewed for strict standards
compliance.

My interest in SafeIntLib was renewed recently, upon seeing:

[edk2] [Patch 05/10] OvmfPkg: Add SafeIntLib and BmpSupportLib to DSC
                     files
[edk2] [Patch 10/10] ArmVirtPkg: Add SafeIntLib and BmpSupportLib to DSC
                     files

With those patches committed (which is the current status), OvmfPkg and
ArmVirtPkg produce and include EFI binaries that contain SafeIntLib
code, according to the build report files -- namely
BootGraphicsResourceTableDxe. (As Mike explained in the thread,
BootGraphicsResourceTableDxe uses BmpSupportLib, and BaseBmpSupportLib
uses SafeIntLib as part of the pixel format conversion, and/or as part
of the BMP<->GOP BLT format conversion -- if I understood correctly.)

Due to SafeIntLib being indirectly pulled into the OVMF and ArmVirt
firmware binaries (and due to expecting more wide-spread use of
SafeIntLib in the future -- which is a good thing!), I figured I'd take
one look. Because developers frequently miss that signed integer
overflow is actually undefined behavior, I checked SafeInt64Sub().
Indeed it is affected.

I don't necessarily think we should revert the patch, but it certainly
needs a re-evaluation (I proposed a fix for SafeInt64Sub() up-thread).

*Alternatively* -- and we should be fully aware of this as well! --, we
*can* define C language behavior, for edk2, *on top* of ISO C. For
example, we can say, "given the compiler options that we use with edk2,
signed integer overflow is actually well-defined: it behaves as you
would expect from the two's complement representation".

This is a perfectly valid thing to say, and we are already saying things
like it: for example, ISO C also leaves violations of the effective type
/ strict aliasing rules "undefined behavior", but we don't care (edk2 is
chock-full of type punning!): we pass "-fno-strict-aliasing" to all GCC
and CLANG toolchains that we support.


So, my point is, we should be aware of what ISO C says about integer
overflow, and then pick one:

- we target strict ISO C compliance (wrt. integer arithmetic) with
SafeIntLib -- in which case a re-evaluation and patches are necessary,

- or else we define additional C language guarantees, and then we
*ensure* those via compiler flags, universally.

Thanks,
Laszlo


> 
> 
>>> -----Original Message-----
>>> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org]
>>> On Behalf Of Laszlo Ersek
>>> Sent: Tuesday, February 13, 2018 4:24 AM
>>> To: Kinney, Michael D <michael.d.kinney@intel.com>; Sean
>>> Brogan <sean.brogan@microsoft.com>
>>> Cc: edk2-devel@lists.01.org; Gao, Liming
>>> <liming.gao@intel.com>
>>> Subject: Re: [edk2] [Patch] MdePkg/BaseSafeIntLib: Add
>>> SafeIntLib class and instance
>>>
>>> Sean, Michael,
>>>
>>> can you please follow up on this?
>>>
>>> To clarify, I think this is a serious bug in SafeIntLib,
>>> dependent on
>>> what we want to use this library for. As far as I
>>> understand, SafeIntLib
>>> intends to centralize integer manipulation / arithmetic,
>>> so that client
>>> code need not concern itself with overflow checking and
>>> such (on the C
>>> expression level -- it still has to check return
>>> statuses, of course).
>>> In other words, undefined behavior related to integer
>>> arithmetic is
>>> supposed to be prevented in various modules by moving all
>>> such
>>> operations into SafeIntLib, and letting client code use
>>> SafeIntLib APIs.
>>>
>>> However, for this to work, SafeIntLib itself must be 100%
>>> free of
>>> undefined behavior. And that's not the case (unless we
>>> define additional
>>> guarantees -- on top of ISO C -- for edk2 target
>>> architectures). Should
>>> I file a TianoCore BZ? Or is someone already (re)auditing
>>> the library?
>>> Or else, is my concern unjustified? Please comment.
>>>
>>> Thanks,
>>> Laszlo
>>>
>>> On 02/08/18 01:45, Laszlo Ersek wrote:
>>>> On 02/08/18 01:32, Laszlo Ersek wrote:
>>>>> On 12/19/17 20:36, Kinney, Michael D wrote:
>>>>>> From: Sean Brogan <sean.brogan@microsoft.com>
>>>>>>
>>>>>> SafeIntLib provides helper functions to prevent
>>> integer overflow
>>>>>> during type conversion, addition, subtraction, and
>>> multiplication.
>>>>>
>>>>> I clearly cannot review such a huge patch, but I've
>>> noticed something
>>>>> and would like to ask for clarification:
>>>>>
>>>>>> +/**
>>>>>> +  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;
>>>>>> +}
>>>>>
>>>>> Is our goal to
>>>>>
>>>>> (a) catch overflows before the caller goes wrong due
>>> to them, or
>>>>> (b) completely prevent undefined behavior from
>>> happening, even inside
>>>>> SafeInt64Sub()?
>>>>>
>>>>> The above implementation may be good for (a), but it's
>>> not correct for
>>>>> (b). The
>>>>>
>>>>>   SignedResult = Minuend - Subtrahend;
>>>>>
>>>>> subtraction invokes undefined behavior if the result
>>> cannot be
>>>>> represented [*]; the rest of the code cannot help.
>>>>>
>>>>> Now if we say that such subtractions always occur
>>> according to the
>>>>> "usual two's complement definition", on all
>>> architectures that edk2
>>>>> targets, and we're sure that no compiler or analysis
>>> tool will flag --
>>>>> or exploit -- the UB either, then the code is fine;
>>> meaning our choice
>>>>> is (a).
>>>>>
>>>>> But, if (b) is our goal, I would replace the current
>>> error condition with:
>>>>>
>>>>>   (((Subtrahend > 0) && (Minuend < MIN_INT64 +
>>> Subtrahend)) ||
>>>>>    ((Subtrahend < 0) && (Minuend > MAX_INT64 +
>>> Subtrahend)))
>>>>
>>>> To clarify, I wouldn't just replace the error
>>> condition. In addition to
>>>> that, I would remove the SignedResult helper variable
>>> (together with the
>>>> current subtraction), and calculate & assign
>>>>
>>>>   *Result = Minuend - Subtrahend;
>>>>
>>>> only after the error condition fails (i.e. the
>>> subtraction is safe).
>>>>
>>>> Thanks,
>>>> Laszlo
>>>>
>>>>
>>>>> Justification:
>>>>>
>>>>> * Subtrahend==0 can never cause overflow
>>>>>
>>>>> * Subtrahend>0 can only cause overflow at the negative
>>> end, so check
>>>>>   that: (Minuend - Subtrahend < MIN_INT64),
>>> mathematically speaking.
>>>>>   In order to write that down in C, add Subtrahend (a
>>> positive value)
>>>>>   to both sides, yielding (Minuend < MIN_INT64 +
>>> Subtrahend). Here,
>>>>>   (MIN_INT64 + Subtrahend) will never go out of range,
>>> because
>>>>>   Subtrahend is positive, and (MIN_INT64 + MAX_INT64)
>>> is representable.
>>>>>
>>>>> * Subtrahend<0 can only cause overflow at the positive
>>> end, so check
>>>>>   that: (Minuend - Subtrahend > MAX_INT64),
>>> mathematically speaking.
>>>>>   In order to write that down in C, add Subtrahend (a
>>> negative value)
>>>>>   to both sides, yielding (Minuend > MAX_INT64 +
>>> Subtrahend). Here,
>>>>>   (MAX_INT64 + Subtrahend) will never go out of range,
>>> because
>>>>>   Subtrahend is negative, and (MAX_INT64 + MIN_INT64)
>>> is representable.
>>>>>
>>>>> (
>>>>>
>>>>> [*] ISO C99 section 6.5 Expressions, p5: "If an
>>> exceptional condition
>>>>> occurs during the evaluation of an expression (that
>>> is, if the result is
>>>>> not mathematically defined or not in the range of
>>> representable values
>>>>> for its type), the behavior is undefined."
>>>>>
>>>>> Section 6.2.5 Types, p9 only exempts unsigned
>>> integers, "A computation
>>>>> involving unsigned operands can never overflow,
>>> because a result that
>>>>> cannot be represented by the resulting unsigned
>>> integer type is reduced
>>>>> modulo the number that is one greater than the largest
>>> value that can be
>>>>> represented by the resulting type."
>>>>>
>>>>> Note that this is different from conversion, where the
>>> computation first
>>>>> succeeds (= we have a value), and then the value is
>>> converted to a type
>>>>> that causes truncation: section 6.3.1.3 Signed and
>>> unsigned integers,
>>>>> p3: "Otherwise, the new type is signed and the value
>>> cannot be
>>>>> represented in it; either the result is
>>> implementation-defined or an
>>>>> implementation-defined signal is raised."
>>>>>
>>>>> In the code above, the expression (Minuend -
>>> Subtrahend) can invoke
>>>>> undefined behavior, there is no conversion (not even
>>> as part of the
>>>>> assignment to SignedResult).
>>>>>
>>>>> )
>>>>>
>>>>> Thanks,
>>>>> Laszlo
>>>>> _______________________________________________
>>>>> edk2-devel mailing list
>>>>> edk2-devel@lists.01.org
>>>>> https://lists.01.org/mailman/listinfo/edk2-devel
>>>>>
>>>>
>>>> _______________________________________________
>>>> edk2-devel mailing list
>>>> edk2-devel@lists.01.org
>>>> https://lists.01.org/mailman/listinfo/edk2-devel
>>>>
>>>
>>> _______________________________________________
>>> edk2-devel mailing list
>>> edk2-devel@lists.01.org
>>> https://lists.01.org/mailman/listinfo/edk2-devel
>> _______________________________________________
>> edk2-devel mailing list
>> edk2-devel@lists.01.org
>> https://lists.01.org/mailman/listinfo/edk2-devel



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance
  2018-02-13 17:51           ` Laszlo Ersek
@ 2018-02-13 17:55             ` Ard Biesheuvel
  2018-02-13 18:03             ` Laszlo Ersek
  1 sibling, 0 replies; 16+ messages in thread
From: Ard Biesheuvel @ 2018-02-13 17:55 UTC (permalink / raw)
  To: Laszlo Ersek
  Cc: Kinney, Michael D, Sean Brogan, Bret Barkelew,
	edk2-devel@lists.01.org, Gao, Liming

On 13 February 2018 at 17:51, Laszlo Ersek <lersek@redhat.com> wrote:
> On 02/13/18 18:18, Ard Biesheuvel wrote:
>> On 13 February 2018 at 16:17, Kinney, Michael D
>> <michael.d.kinney@intel.com> wrote:
>>> +Bret
>>>
>>> Mike
>>>
>>
>> Why has this patch been submitted if there are unanswered questions of
>> such a fundamental nature?
>> Could someone please revert it until there is agreement about its
>> inclusion (and in which form)?
>
> I think your question is "why has this patch been *committed* / pushed
> if such questions remain"; is that correct?
>

Ah yes, apologies.

> The patch was correctly submitted to edk2-devel for review back in
> December 2017. At that time I quickly glanced at the diffstat, and I
> didn't even start reviewing the patch -- "15 files changed, 8915
> insertions(+), 9 deletions(-)". For me to review such a large amount of
> code in detail, it would have to be split into tens of patches, and I'd
> likely have to work on the review intensely for a week or more. So, I
> asumed that SafeIntLib had been carefully reviewed for strict standards
> compliance.
>
> My interest in SafeIntLib was renewed recently, upon seeing:
>
> [edk2] [Patch 05/10] OvmfPkg: Add SafeIntLib and BmpSupportLib to DSC
>                      files
> [edk2] [Patch 10/10] ArmVirtPkg: Add SafeIntLib and BmpSupportLib to DSC
>                      files
>
> With those patches committed (which is the current status), OvmfPkg and
> ArmVirtPkg produce and include EFI binaries that contain SafeIntLib
> code, according to the build report files -- namely
> BootGraphicsResourceTableDxe. (As Mike explained in the thread,
> BootGraphicsResourceTableDxe uses BmpSupportLib, and BaseBmpSupportLib
> uses SafeIntLib as part of the pixel format conversion, and/or as part
> of the BMP<->GOP BLT format conversion -- if I understood correctly.)
>
> Due to SafeIntLib being indirectly pulled into the OVMF and ArmVirt
> firmware binaries (and due to expecting more wide-spread use of
> SafeIntLib in the future -- which is a good thing!), I figured I'd take
> one look. Because developers frequently miss that signed integer
> overflow is actually undefined behavior, I checked SafeInt64Sub().
> Indeed it is affected.
>
> I don't necessarily think we should revert the patch, but it certainly
> needs a re-evaluation (I proposed a fix for SafeInt64Sub() up-thread).
>
> *Alternatively* -- and we should be fully aware of this as well! --, we
> *can* define C language behavior, for edk2, *on top* of ISO C. For
> example, we can say, "given the compiler options that we use with edk2,
> signed integer overflow is actually well-defined: it behaves as you
> would expect from the two's complement representation".
>
> This is a perfectly valid thing to say, and we are already saying things
> like it: for example, ISO C also leaves violations of the effective type
> / strict aliasing rules "undefined behavior", but we don't care (edk2 is
> chock-full of type punning!): we pass "-fno-strict-aliasing" to all GCC
> and CLANG toolchains that we support.
>
>
> So, my point is, we should be aware of what ISO C says about integer
> overflow, and then pick one:
>
> - we target strict ISO C compliance (wrt. integer arithmetic) with
> SafeIntLib -- in which case a re-evaluation and patches are necessary,
>
> - or else we define additional C language guarantees, and then we
> *ensure* those via compiler flags, universally.
>
> Thanks,
> Laszlo
>
>
>>
>>
>>>> -----Original Message-----
>>>> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org]
>>>> On Behalf Of Laszlo Ersek
>>>> Sent: Tuesday, February 13, 2018 4:24 AM
>>>> To: Kinney, Michael D <michael.d.kinney@intel.com>; Sean
>>>> Brogan <sean.brogan@microsoft.com>
>>>> Cc: edk2-devel@lists.01.org; Gao, Liming
>>>> <liming.gao@intel.com>
>>>> Subject: Re: [edk2] [Patch] MdePkg/BaseSafeIntLib: Add
>>>> SafeIntLib class and instance
>>>>
>>>> Sean, Michael,
>>>>
>>>> can you please follow up on this?
>>>>
>>>> To clarify, I think this is a serious bug in SafeIntLib,
>>>> dependent on
>>>> what we want to use this library for. As far as I
>>>> understand, SafeIntLib
>>>> intends to centralize integer manipulation / arithmetic,
>>>> so that client
>>>> code need not concern itself with overflow checking and
>>>> such (on the C
>>>> expression level -- it still has to check return
>>>> statuses, of course).
>>>> In other words, undefined behavior related to integer
>>>> arithmetic is
>>>> supposed to be prevented in various modules by moving all
>>>> such
>>>> operations into SafeIntLib, and letting client code use
>>>> SafeIntLib APIs.
>>>>
>>>> However, for this to work, SafeIntLib itself must be 100%
>>>> free of
>>>> undefined behavior. And that's not the case (unless we
>>>> define additional
>>>> guarantees -- on top of ISO C -- for edk2 target
>>>> architectures). Should
>>>> I file a TianoCore BZ? Or is someone already (re)auditing
>>>> the library?
>>>> Or else, is my concern unjustified? Please comment.
>>>>
>>>> Thanks,
>>>> Laszlo
>>>>
>>>> On 02/08/18 01:45, Laszlo Ersek wrote:
>>>>> On 02/08/18 01:32, Laszlo Ersek wrote:
>>>>>> On 12/19/17 20:36, Kinney, Michael D wrote:
>>>>>>> From: Sean Brogan <sean.brogan@microsoft.com>
>>>>>>>
>>>>>>> SafeIntLib provides helper functions to prevent
>>>> integer overflow
>>>>>>> during type conversion, addition, subtraction, and
>>>> multiplication.
>>>>>>
>>>>>> I clearly cannot review such a huge patch, but I've
>>>> noticed something
>>>>>> and would like to ask for clarification:
>>>>>>
>>>>>>> +/**
>>>>>>> +  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;
>>>>>>> +}
>>>>>>
>>>>>> Is our goal to
>>>>>>
>>>>>> (a) catch overflows before the caller goes wrong due
>>>> to them, or
>>>>>> (b) completely prevent undefined behavior from
>>>> happening, even inside
>>>>>> SafeInt64Sub()?
>>>>>>
>>>>>> The above implementation may be good for (a), but it's
>>>> not correct for
>>>>>> (b). The
>>>>>>
>>>>>>   SignedResult = Minuend - Subtrahend;
>>>>>>
>>>>>> subtraction invokes undefined behavior if the result
>>>> cannot be
>>>>>> represented [*]; the rest of the code cannot help.
>>>>>>
>>>>>> Now if we say that such subtractions always occur
>>>> according to the
>>>>>> "usual two's complement definition", on all
>>>> architectures that edk2
>>>>>> targets, and we're sure that no compiler or analysis
>>>> tool will flag --
>>>>>> or exploit -- the UB either, then the code is fine;
>>>> meaning our choice
>>>>>> is (a).
>>>>>>
>>>>>> But, if (b) is our goal, I would replace the current
>>>> error condition with:
>>>>>>
>>>>>>   (((Subtrahend > 0) && (Minuend < MIN_INT64 +
>>>> Subtrahend)) ||
>>>>>>    ((Subtrahend < 0) && (Minuend > MAX_INT64 +
>>>> Subtrahend)))
>>>>>
>>>>> To clarify, I wouldn't just replace the error
>>>> condition. In addition to
>>>>> that, I would remove the SignedResult helper variable
>>>> (together with the
>>>>> current subtraction), and calculate & assign
>>>>>
>>>>>   *Result = Minuend - Subtrahend;
>>>>>
>>>>> only after the error condition fails (i.e. the
>>>> subtraction is safe).
>>>>>
>>>>> Thanks,
>>>>> Laszlo
>>>>>
>>>>>
>>>>>> Justification:
>>>>>>
>>>>>> * Subtrahend==0 can never cause overflow
>>>>>>
>>>>>> * Subtrahend>0 can only cause overflow at the negative
>>>> end, so check
>>>>>>   that: (Minuend - Subtrahend < MIN_INT64),
>>>> mathematically speaking.
>>>>>>   In order to write that down in C, add Subtrahend (a
>>>> positive value)
>>>>>>   to both sides, yielding (Minuend < MIN_INT64 +
>>>> Subtrahend). Here,
>>>>>>   (MIN_INT64 + Subtrahend) will never go out of range,
>>>> because
>>>>>>   Subtrahend is positive, and (MIN_INT64 + MAX_INT64)
>>>> is representable.
>>>>>>
>>>>>> * Subtrahend<0 can only cause overflow at the positive
>>>> end, so check
>>>>>>   that: (Minuend - Subtrahend > MAX_INT64),
>>>> mathematically speaking.
>>>>>>   In order to write that down in C, add Subtrahend (a
>>>> negative value)
>>>>>>   to both sides, yielding (Minuend > MAX_INT64 +
>>>> Subtrahend). Here,
>>>>>>   (MAX_INT64 + Subtrahend) will never go out of range,
>>>> because
>>>>>>   Subtrahend is negative, and (MAX_INT64 + MIN_INT64)
>>>> is representable.
>>>>>>
>>>>>> (
>>>>>>
>>>>>> [*] ISO C99 section 6.5 Expressions, p5: "If an
>>>> exceptional condition
>>>>>> occurs during the evaluation of an expression (that
>>>> is, if the result is
>>>>>> not mathematically defined or not in the range of
>>>> representable values
>>>>>> for its type), the behavior is undefined."
>>>>>>
>>>>>> Section 6.2.5 Types, p9 only exempts unsigned
>>>> integers, "A computation
>>>>>> involving unsigned operands can never overflow,
>>>> because a result that
>>>>>> cannot be represented by the resulting unsigned
>>>> integer type is reduced
>>>>>> modulo the number that is one greater than the largest
>>>> value that can be
>>>>>> represented by the resulting type."
>>>>>>
>>>>>> Note that this is different from conversion, where the
>>>> computation first
>>>>>> succeeds (= we have a value), and then the value is
>>>> converted to a type
>>>>>> that causes truncation: section 6.3.1.3 Signed and
>>>> unsigned integers,
>>>>>> p3: "Otherwise, the new type is signed and the value
>>>> cannot be
>>>>>> represented in it; either the result is
>>>> implementation-defined or an
>>>>>> implementation-defined signal is raised."
>>>>>>
>>>>>> In the code above, the expression (Minuend -
>>>> Subtrahend) can invoke
>>>>>> undefined behavior, there is no conversion (not even
>>>> as part of the
>>>>>> assignment to SignedResult).
>>>>>>
>>>>>> )
>>>>>>
>>>>>> Thanks,
>>>>>> Laszlo
>>>>>> _______________________________________________
>>>>>> edk2-devel mailing list
>>>>>> edk2-devel@lists.01.org
>>>>>> https://lists.01.org/mailman/listinfo/edk2-devel
>>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> edk2-devel mailing list
>>>>> edk2-devel@lists.01.org
>>>>> https://lists.01.org/mailman/listinfo/edk2-devel
>>>>>
>>>>
>>>> _______________________________________________
>>>> edk2-devel mailing list
>>>> edk2-devel@lists.01.org
>>>> https://lists.01.org/mailman/listinfo/edk2-devel
>>> _______________________________________________
>>> edk2-devel mailing list
>>> edk2-devel@lists.01.org
>>> https://lists.01.org/mailman/listinfo/edk2-devel
>


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance
  2018-02-13 17:15           ` Andrew Fish
@ 2018-02-13 17:55             ` Laszlo Ersek
  0 siblings, 0 replies; 16+ messages in thread
From: Laszlo Ersek @ 2018-02-13 17:55 UTC (permalink / raw)
  To: Andrew Fish, Bret Barkelew
  Cc: Mike Kinney, Sean Brogan, edk2-devel@lists.01.org, Gao, Liming

On 02/13/18 18:15, Andrew Fish wrote:
> 
> 
>> On Feb 13, 2018, at 8:56 AM, Bret Barkelew
>> <Bret.Barkelew@microsoft.com <mailto:Bret.Barkelew@microsoft.com>> wrote:
>>
>> In response to the original question, I would content that our goal
>> should be "a". We should be allowing universal detection of errors
>> without the caller having to carry this detection code itself.
>>
>> The analog would be the safe string functions: if a buffer overflow
>> occurs, they don't find a way to "fix" the operation, but they
>> faithfully report an error.
>>
>> As such, I believe from my review that these functions work as intended.
>>
> 
> Bret,
> 
> I think Lazlo's point is that undefined behavior[1]  can cause the math
> function to break in the future and that we have to be very pedantic in
> how it is coded.

That's *exactly* my point, yes.

> Per the C standard it is legal for the compiler to
> optimized away undefined behavior[2], and clang is very aggressive about
> warning on undefined behavior and then updating the optimizer to remove
> the code in a future release.

Thank you for the independent confirmation :) (I'm reading and answering
your email after sending my previous one.)

> For example the BaseTool compression code
> broke with Xcode 9 recently due to the presence of an illegal 32-bit
> shift that was only hit when the optimizer inlined the function. While
> the compiler tries to emit warnings, or at least traps, for undefined
> behavior what we have seen with the Link Time Optimization is the code
> can just get removed. 

Huge kudos for this example!

> 
> [1] - Kind of clangs point of view on undefined behavior in
> C: http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html
> [2] - Example of undefined behavior in clang that emits a trap.
> Dereferencing NULL is undefined behavior in C so clang emits a trap, and
> optimizes way the code after the trap. 
> 
> ~/work/Compiler>cat undefined.c
> 
> int
> main ()
> {
>   int *Yikes = 0;
> 
>   *Yikes = 1;
>   return 0;
> }
> 
> ~/work/Compiler>clang -S -Os undefined.c
> ~/work/Compiler>cat undefined.S
> .section__TEXT,__text,regular,pure_instructions
> .macosx_version_min 10, 12
> .globl_main
> _main:                                  ## @main
> .cfi_startproc
> ## BB#0:
> pushq%rbp
> Lcfi0:
> .cfi_def_cfa_offset 16
> Lcfi1:
> .cfi_offset %rbp, -16
> movq%rsp, %rbp
> Lcfi2:
> .cfi_def_cfa_register %rbp
> ud2
> .cfi_endproc
> 
> 
> .subsections_via_symbols

and for this one.

Thank you!
Laszlo


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance
  2018-02-13 17:51           ` Laszlo Ersek
  2018-02-13 17:55             ` Ard Biesheuvel
@ 2018-02-13 18:03             ` Laszlo Ersek
  1 sibling, 0 replies; 16+ messages in thread
From: Laszlo Ersek @ 2018-02-13 18:03 UTC (permalink / raw)
  To: Ard Biesheuvel, Kinney, Michael D
  Cc: Sean Brogan, Bret Barkelew, edk2-devel@lists.01.org, Gao, Liming

On 02/13/18 18:51, Laszlo Ersek wrote:

> So, my point is, we should be aware of what ISO C says about integer
> overflow, and then pick one:
>
> - we target strict ISO C compliance (wrt. integer arithmetic) with
> SafeIntLib -- in which case a re-evaluation and patches are necessary,
>
> - or else we define additional C language guarantees, and then we
> *ensure* those via compiler flags, universally.

Specifically, see "-fwrapv" for GCC:

       -fwrapv
           This option instructs the compiler to assume that signed
           arithmetic overflow of addition, subtraction and
           multiplication wraps around using twos-complement
           representation.  This flag enables some optimizations and
           disables others.  This option is enabled by default for the
           Java front end, as required by the Java language
           specification.

It is used by QEMU, for example. Citing the "configure" script:

> # default flags for all hosts
> # We use -fwrapv to tell the compiler that we require a C dialect where
> # left shift of signed integers is well defined and has the expected
> # 2s-complement style results. (Both clang and gcc agree that it
> # provides these semantics.)
> QEMU_CFLAGS="-fno-strict-aliasing -fno-common -fwrapv $QEMU_CFLAGS"

edk2 doesn't use "-fwrapv" (yet?), and I'm not sure an equivalent flag
exists for VS / MSVC at all.

Thanks!
Laszlo


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance
  2018-02-13 17:29           ` Laszlo Ersek
@ 2018-02-13 18:19             ` Bret Barkelew
  0 siblings, 0 replies; 16+ messages in thread
From: Bret Barkelew @ 2018-02-13 18:19 UTC (permalink / raw)
  To: Laszlo Ersek, Kinney, Michael D, Sean Brogan
  Cc: edk2-devel@lists.01.org, Gao, Liming

Ah, yes, this makes more sense. It was difficult to review all your comments on my phone.

Thanks for clarifying!

- Bret

From: Laszlo Ersek<mailto:lersek@redhat.com>
Sent: Tuesday, February 13, 2018 9:29 AM
To: Bret Barkelew<mailto:Bret.Barkelew@microsoft.com>; Kinney, Michael D<mailto:michael.d.kinney@intel.com>; Sean Brogan<mailto:sean.brogan@microsoft.com>
Cc: edk2-devel@lists.01.org<mailto:edk2-devel@lists.01.org>; Gao, Liming<mailto:liming.gao@intel.com>
Subject: Re: [edk2] [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance

On 02/13/18 17:56, Bret Barkelew wrote:
> In response to the original question, I would content that our goal
> should be "a". We should be allowing universal detection of errors
> without the caller having to carry this detection code itself.

OK.

The question is how the detection is implemented internally. Is that
implementation (in edk2) allowed to rely on behavior that the ISO C
standard leaves undefined, and -- consequently -- compilers might
exploit for code generation?

> The analog would be the safe string functions: if a buffer overflow
> occurs, they don't find a way to "fix" the operation, but they
> faithfully report an error.

Precisely.

Correspondingly, translated to the safe string functions, my question
becomes:

Is the implementation of the safe string functions allowed to employ
buffer overflow internally, and detect the overflow after the fact?

> As such, I believe from my review that these functions work as
> intended.

Please let me quote the function again, from
"MdePkg/Library/BaseSafeIntLib/SafeIntLib.c":

  3831  RETURN_STATUS
  3832  EFIAPI
  3833  SafeInt64Sub (
  3834    IN  INT64  Minuend,
  3835    IN  INT64  Subtrahend,
  3836    OUT INT64  *Result
  3837    )
  3838  {
  3839    RETURN_STATUS  Status;
  3840    INT64          SignedResult;
  3841
  3842    if (Result == NULL) {
  3843      return RETURN_INVALID_PARAMETER;
  3844    }
  3845
  3846    SignedResult = Minuend - Subtrahend;
  3847
  3848    //
  3849    // Subtracting a positive number from a positive number never overflows.
  3850    // Subtracting a negative number from a negative number never overflows.
  3851    // If you subtract a negative number from a positive number, you expect a positive result.
  3852    // If you subtract a positive number from a negative number, you expect a negative result.
  3853    // Overflow if inputs vary in sign and the output does not have the same sign as the first input.
  3854    //
  3855    if (((Minuend < 0) != (Subtrahend < 0)) &&
  3856        ((Minuend < 0) != (SignedResult < 0))) {
  3857      *Result = INT64_ERROR;
  3858      Status = RETURN_BUFFER_TOO_SMALL;
  3859    } else {
  3860      *Result = SignedResult;
  3861      Status = RETURN_SUCCESS;
  3862    }
  3863
  3864    return Status;
  3865  }

On line 3846, integer overflow is possible. If that happens, not only is
the resultant value of "SignedResult" undefined, but the behavior of the
rest of the function is undefined, according to ISO C.

In other words, just because we move the checking into a library
function, we cannot check *after the fact*. The subtraction on line 3846
can invoke undefined behavior *first*, and we check only afterwards,
starting on line 3855.

Here's an analogy. Various C compilers regularly equate "undefined
behavior" with "never happens" (which is a valid interpretation of the
ISO C standard for the compiler to make). For example, given the code

  int f(int *x)
  {
    *x = 3;
    if (x == NULL) {
      return 1;
    }
    return 0;
}

the compiler may compile f() to unconditionally return 0, such as:

  int f(int *x)
  {
    *x = 3;
    return 0;
  }

Because, the (x == NULL) branch would depend on undefined behavior
invoked by the assignment to *x. Given that the (*x = 3) assignment is
undefined for (x==NULL), according to ISO C, the subsequent (x == NULL)
check can be taken as constant false, and eliminated.

Similarly, a sufficiently smart compiler may assume that the subtraction
on line 3846 will never overflow. (Because, such an overflow would be
undefined behavior.) Consequently, it may deduce that the overflow
checks, *after the fact*, evaluate to constant false, and can be
eliminated. It might compile the function as in:

  {
    RETURN_STATUS  Status;
    INT64          SignedResult;

    if (Result == NULL) {
      return RETURN_INVALID_PARAMETER;
    }

    SignedResult = Minuend - Subtrahend;

    *Result = SignedResult;
    Status = RETURN_SUCCESS;

    return Status;
  }

I apoligize if I'm unclear; I really don't know how to put it better.
The subtraction on line 3846 runs the risk of undefined behavior, and
the checks starting on line 3855 are too late.

Thanks
Laszlo



^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2018-02-13 18:13 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-12-19 19:36 [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance Kinney, Michael D
2018-01-18  8:09 ` Sean Brogan
2018-01-19  7:48   ` Gao, Liming
2018-02-08  0:32 ` Laszlo Ersek
2018-02-08  0:45   ` Laszlo Ersek
2018-02-13 12:23     ` Laszlo Ersek
2018-02-13 16:17       ` Kinney, Michael D
2018-02-13 16:56         ` Bret Barkelew
2018-02-13 17:15           ` Andrew Fish
2018-02-13 17:55             ` Laszlo Ersek
2018-02-13 17:29           ` Laszlo Ersek
2018-02-13 18:19             ` Bret Barkelew
2018-02-13 17:18         ` Ard Biesheuvel
2018-02-13 17:51           ` Laszlo Ersek
2018-02-13 17:55             ` Ard Biesheuvel
2018-02-13 18:03             ` Laszlo Ersek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox