From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.65; helo=mga03.intel.com; envelope-from=michael.d.kinney@intel.com; receiver=edk2-devel@lists.01.org Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id E18BF2208589C for ; Tue, 19 Dec 2017 11:31:44 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 19 Dec 2017 11:36:30 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.45,428,1508828400"; d="scan'208";a="188407752" Received: from mdkinney-mobl2.amr.corp.intel.com ([10.241.98.58]) by fmsmga006.fm.intel.com with ESMTP; 19 Dec 2017 11:36:29 -0800 From: "Kinney, Michael D" To: edk2-devel@lists.01.org Cc: Sean Brogan , Liming Gao , Michael D Kinney Date: Tue, 19 Dec 2017 11:36:25 -0800 Message-Id: <20171219193625.16060-1-michael.d.kinney@intel.com> X-Mailer: git-send-email 2.14.2.windows.3 Subject: [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 19 Dec 2017 19:31:45 -0000 From: Sean Brogan 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 Cc: Liming Gao Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney --- 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.
+ Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.
@@ -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.
+ Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
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.
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
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.
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.
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 +#include + + +// +// 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 +#include + +/** + 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 +#include + +/** + 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 +#include + +/** + 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