From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=104.47.32.94; helo=nam01-sn1-obe.outbound.protection.outlook.com; envelope-from=sean.brogan@microsoft.com; receiver=edk2-devel@lists.01.org Received: from NAM01-SN1-obe.outbound.protection.outlook.com (mail-sn1nam01on0094.outbound.protection.outlook.com [104.47.32.94]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 13E922220D1FA for ; Thu, 18 Jan 2018 00:04:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=A6JBDY/Ka5DrHiqsdXdRVdLbOpfmacFuBNOdzz7i8Tg=; b=B3PDgMIxt0yS+bREXyzYR0EdhZtGurLIMLKyZ7KuhT9KjuT4Gt2cUWzsNTpQoN2gCuSkLCLgD4b7m3XL3fR0kIjcwV56wHS73g2yAxTj0eba6egXy0dyvo34aba+AOCqiW8JIxKpF7VaX70oGVruJhAyP2RtRcQAe/krKni+OMQ= Received: from MWHPR21MB0480.namprd21.prod.outlook.com (10.172.102.19) by MWHPR21MB0191.namprd21.prod.outlook.com (10.173.52.137) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.444.5; Thu, 18 Jan 2018 08:09:30 +0000 Received: from MWHPR21MB0480.namprd21.prod.outlook.com ([10.172.102.19]) by MWHPR21MB0480.namprd21.prod.outlook.com ([10.172.102.19]) with mapi id 15.20.0444.004; Thu, 18 Jan 2018 08:09:30 +0000 From: Sean Brogan To: "Kinney, Michael D" , "edk2-devel@lists.01.org" CC: "Gao, Liming" Thread-Topic: [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance Thread-Index: AQHTeQCvdN1Y6azP10y9/1G/vdUaQKN5dU2g Date: Thu, 18 Jan 2018 08:09:29 +0000 Message-ID: References: <20171219193625.16060-1-michael.d.kinney@intel.com> In-Reply-To: <20171219193625.16060-1-michael.d.kinney@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: msip_labels: MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Enabled=True; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_SiteId=72f988bf-86f1-41af-91ab-2d7cd011db47; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Owner=sebrogan@microsoft.com; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_SetDate=2018-01-18T08:09:24.6807058Z; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Name=General; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Application=Microsoft Azure Information Protection; MSIP_Label_f42aa342-8706-4288-bd11-ebb85995028c_Extended_MSFT_Method=Automatic; Sensitivity=General x-originating-ip: [50.47.104.211] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; MWHPR21MB0191; 6:JyLHClZBshV81l8mcDqQ+2MP5w+Q6ZbU8W1CXlAi66zLJBiV5gIcE0fj0iBSGrc2SZ4gyilkfUOD4LTfvxxI/ue16xTfgAeQHX9TxNqHxcAMliiCrOeRMvZe1CUqgGDrKiQxLTbChFZVZZdVZDB1/GDgYc63BW0NnScj1fGD/HiJgngmAQrS0RMXOjRB1w8ghF3ThLTL87b2+paFmPDxyeQQV5+fYvzyEyqk+2Gzc4uPffzk+BcRyAuwOWHqYvzdiQA+s9jKwq9HWkQ+kGO+6ZY9fUNM3zT2LwZYBuZR/DDl+ydtgmot1Qu9XKketNl7UGhVxETTG09J3tc+QZsV9+naTFNQ1V3D/ivCmA+TtsErP6DxKhQcnAZZgjFe9yFK; 5:OWS7gx5dRmTDN+oDVTasf9/LuDk4qPvcAYKA3L1gQbAnnunjMyw5QQYfi4zen2XDxl6YtRZKymgrDkqxEJ3ciNTrz0GCxXKBnL84xeN+En1YixN56+nKN7njjXDUUeGnd31vbcAQE1Fr9O7v7Mwlj+jv/nLNJGGnFaBYe60Yts4=; 24:R8IHYGOftOSCHbvhYnp05/qXx4AA1fz05F1mdVqKdDnR/Ui2S5WyggSBjTe6zLKJQHlPPKomV5jiktbSDQIgR0K4hhlJYhXfRLz2tsbp+vw=; 7:pX8wqAZ9OSEFRCs6923qw7l8tA+5JNJqvNNYO18hdica49RJLzV/bUIaHn38UfW6IAlJYKfBGaAEKSVv2oo7IKFKT0qRdeS6sG//Cpy5ePtHDzyV1SiqCZmdJ+9hjdhBbrq404xxqTeT0+dDZvmKW7eO0+bALK5Ey25wBLmCHLQGNTLKFfXhB9hIwfoc86ab0EPaQy9IzDkpccAA9Wh89Oy7hH9aBR0TrYMBKnGpVWtJHDgpTOFEGQQr8hBVUXmw x-ms-exchange-antispam-srfa-diagnostics: SSOS; x-ms-office365-filtering-correlation-id: 883df903-d29c-4a3b-3b68-08d55e4accda x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(5600026)(4604075)(3008032)(4534125)(4602075)(4627221)(201703031133081)(201702281549075)(48565401081)(2017052603307)(7193020); SRVR:MWHPR21MB0191; x-ms-traffictypediagnostic: MWHPR21MB0191: x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(28532068793085)(89211679590171)(162533806227266)(228905959029699); x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(61425038)(6040492)(2401047)(8121501046)(5005006)(3002001)(93006095)(93001095)(10201501046)(3231046)(2400058)(944501161)(6055026)(61426038)(61427038)(6041279)(20161123558120)(20161123560045)(20161123564045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123562045)(6072148)(201708071742011); SRVR:MWHPR21MB0191; BCL:0; PCL:0; RULEID:(100000803126)(100110400120); SRVR:MWHPR21MB0191; x-forefront-prvs: 05568D1FF7 x-forefront-antispam-report: SFV:NSPM; SFS:(10019020)(366004)(39860400002)(39380400002)(346002)(376002)(396003)(189003)(199004)(13464003)(22452003)(8936002)(106356001)(316002)(81156014)(6116002)(81166006)(3846002)(66066001)(8676002)(10090500001)(53936002)(53946003)(16200700003)(2950100002)(6436002)(229853002)(55016002)(9686003)(86612001)(33656002)(110136005)(5660300001)(99286004)(102836004)(4326008)(478600001)(3280700002)(7736002)(2501003)(26005)(10290500003)(77096007)(74316002)(305945005)(86362001)(575784001)(14454004)(6346003)(59450400001)(8990500004)(76176011)(2900100001)(68736007)(6506007)(3660700001)(53546011)(105586002)(97736004)(25786009)(7696005)(2906002)(6246003)(579004)(569006); DIR:OUT; SFP:1102; SCL:1; SRVR:MWHPR21MB0191; H:MWHPR21MB0480.namprd21.prod.outlook.com; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; received-spf: None (protection.outlook.com: microsoft.com does not designate permitted sender hosts) authentication-results: spf=none (sender IP is ) smtp.mailfrom=sean.brogan@microsoft.com; x-microsoft-antispam-message-info: 1Z3693Pj/ZAT8U7ck5G/8xJUcw1YRpF89QrwgfwRKMyfSRgwyE1K6EaLY7vAExvnpU3FlOM+fEoWe72xQvjVgQ== spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: microsoft.com X-MS-Exchange-CrossTenant-Network-Message-Id: 883df903-d29c-4a3b-3b68-08d55e4accda X-MS-Exchange-CrossTenant-originalarrivaltime: 18 Jan 2018 08:09:29.7405 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR21MB0191 Subject: Re: [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 18 Jan 2018 08:04:17 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Sean Brogan -----Original Message----- From: Kinney, Michael D [mailto:michael.d.kinney@intel.com]=20 Sent: Tuesday, December 19, 2017 11:36 AM To: edk2-devel@lists.01.org Cc: Sean Brogan ; Gao, Liming ; Kinney, Michael D Subject: [Patch] MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance From: Sean Brogan SafeIntLib provides helper functions to prevent integer overflow during type conversion, addition, subtraction, and multiplication. Conversion Functions =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D * 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D * Unsigned integer math functions protect from overflow and underflow (in case of subtraction). Signed Addition, Subtraction, Multiplication =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D * 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/AArch6= 4/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/Proces= sorBind.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 BS= D 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/Proces= sorBind.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 compi= ler 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 availabl= e under the terms and conditions of the BSD License that accompanies this distribu= tion. 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/Proc= essorBind.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/Proces= sorBind.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) p= rocessors. -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 availabl= e 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/S= afeIntLib.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 durin= g + 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 m= et: + 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 not= ice, + this list of conditions and the following disclaimer in the documentatio= n + 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 IM= PLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE D= ISCLAIMED. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY= DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCL= UDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF= USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY TH= EORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEG= LIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN I= F + 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 w= e are +// converting to is unsigned. +// + +/** + INT8 -> UINT8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 condit= ion, + then Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 condit= ion, + then Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is return= ed. + + @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 condit= ion, + then Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is return= ed. + + @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 condit= ion, + then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 condit= ion, + then Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is return= ed. + + @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 condit= ion, + then Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 condit= ion, + then Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is return= ed. + + @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 condit= ion, + then Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is return= ed. + + @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 condit= ion, + then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 condit= ion, + then Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is return= ed. + + @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 condit= ion, + then Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @param[in] Multiplicand A number that is to be multiplied by another + @param[in] Multiplier A number by which the multiplicand is to be m= ultiplied + @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 condit= ion, + then Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is return= ed. + + @param[in] Multiplicand A number that is to be multiplied by another + @param[in] Multiplier A number by which the multiplicand is to be m= ultiplied + @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 condit= ion, + then Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is return= ed. + + @param[in] Multiplicand A number that is to be multiplied by another + @param[in] Multiplier A number by which the multiplicand is to be m= ultiplied + @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 condit= ion, + then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @param[in] Multiplicand A number that is to be multiplied by another + @param[in] Multiplier A number by which the multiplicand is to be m= ultiplied + @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 condit= ion, + then Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is return= ed. + + @param[in] Multiplicand A number that is to be multiplied by another + @param[in] Multiplier A number by which the multiplicand is to be m= ultiplied + @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 numb= er, +// 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 you= r +// 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 condit= ion, + 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 condit= ion, + then Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 condit= ion, + then Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 condit= ion, + then Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 condit= ion, + 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 condit= ion, + then Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 condit= ion, + 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 condit= ion, + then Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 condit= ion, + then Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 condit= ion, + then Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 condit= ion, + 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 condit= ion, + then Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 condit= ion, + 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 m= ultiplied + @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 condit= ion, + then Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @param[in] Multiplicand A number that is to be multiplied by another + @param[in] Multiplier A number by which the multiplicand is to be m= ultiplied + @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 condit= ion, + then Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @param[in] Multiplicand A number that is to be multiplied by another + @param[in] Multiplier A number by which the multiplicand is to be m= ultiplied + @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 condit= ion, + then Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @param[in] Multiplicand A number that is to be multiplied by another + @param[in] Multiplier A number by which the multiplicand is to be m= ultiplied + @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 condit= ion, + 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 m= ultiplied + @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 condit= ion, + then Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @param[in] Multiplicand A number that is to be multiplied by another + @param[in] Multiplier A number by which the multiplicand is to be m= ultiplied + @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/Proces= sorBind.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/Libr= ary/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 durin= g +# 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 m= et: +# 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 not= ice, +# this list of conditions and the following disclaimer in the documentatio= n +# 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 IM= PLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE D= ISCLAIMED. +# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY= DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCL= UDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF= USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY TH= EORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEG= LIGENCE +# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN I= F +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D BaseSafeIntLib + FILE_GUID =3D 4EA91BFA-3482-4930-B136-70679C6CE489 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D SafeIntLib + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D 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/Ba= seSafeIntLib/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 durin= g + 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 m= et: + 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 not= ice, + this list of conditions and the following disclaimer in the documentatio= n + 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 IM= PLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE D= ISCLAIMED. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY= DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCL= UDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF= USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY TH= EORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEG= LIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN I= F + 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 w= e are +// converting to is unsigned. +// + +/** + INT8 -> UINT8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand >=3D 0) { + *Result =3D (UINT8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT8 -> CHAR8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand >=3D 0) { + *Result =3D (CHAR8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D CHAR8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT8 -> UINT16 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand >=3D 0) { + *Result =3D (UINT16)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT16_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT8 -> UINT32 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand >=3D 0) { + *Result =3D (UINT32)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT32_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT8 -> UINTN conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand >=3D 0) { + *Result =3D (UINTN)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINTN_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT8 -> UINT64 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand >=3D 0) { + *Result =3D (UINT64)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT64_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINT8 -> INT8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_INT8) { + *Result =3D (INT8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INT8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINT8 -> CHAR8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_INT8) { + *Result =3D (CHAR8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D CHAR8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT16 -> INT8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Operand >=3D MIN_INT8) && (Operand <=3D MAX_INT8)) { + *Result =3D (INT8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INT8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT16 -> CHAR8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Operand >=3D 0) && (Operand <=3D MAX_INT8)) { + *Result =3D (CHAR8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D CHAR8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT16 -> UINT8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Operand >=3D 0) && (Operand <=3D MAX_UINT8)) { + *Result =3D (UINT8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT16 -> UINT16 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand >=3D 0) { + *Result =3D (UINT16)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT16_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT16 -> UINT32 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand >=3D 0) { + *Result =3D (UINT32)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT32_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT16 -> UINTN conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand >=3D 0) { + *Result =3D (UINTN)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINTN_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT16 -> UINT64 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand >=3D 0) { + *Result =3D (UINT64)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT64_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINT16 -> INT8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_INT8) { + *Result =3D (INT8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INT8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINT16 -> CHAR8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_INT8) { + *Result =3D (INT8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D CHAR8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINT16 -> UINT8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_UINT8) { + *Result =3D (UINT8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINT16 -> INT16 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_INT16) { + *Result =3D (INT16)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INT16_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT32 -> INT8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Operand >=3D MIN_INT8) && (Operand <=3D MAX_INT8)) { + *Result =3D (INT8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INT8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT32 -> CHAR8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Operand >=3D 0) && (Operand <=3D MAX_INT8)) { + *Result =3D (CHAR8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D CHAR8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT32 -> UINT8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Operand >=3D 0) && (Operand <=3D MAX_UINT8)) { + *Result =3D (UINT8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT32 -> INT16 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Operand >=3D MIN_INT16) && (Operand <=3D MAX_INT16)) { + *Result =3D (INT16)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INT16_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT32 -> UINT16 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Operand >=3D 0) && (Operand <=3D MAX_UINT16)) { + *Result =3D (UINT16)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT16_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT32 -> UINT32 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand >=3D 0) { + *Result =3D (UINT32)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT32_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT32 -> UINT64 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand >=3D 0) { + *Result =3D (UINT64)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT64_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINT32 -> INT8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_INT8) { + *Result =3D (INT8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INT8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINT32 -> CHAR8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_INT8) { + *Result =3D (INT8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D CHAR8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINT32 -> UINT8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_UINT8) { + *Result =3D (UINT8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINT32 -> INT16 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_INT16) { + *Result =3D (INT16)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INT16_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINT32 -> UINT16 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_UINT16) { + *Result =3D (UINT16)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT16_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINT32 -> INT32 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_INT32) { + *Result =3D (INT32)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INT32_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INTN -> INT8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Operand >=3D MIN_INT8) && (Operand <=3D MAX_INT8)) { + *Result =3D (INT8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INT8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INTN -> CHAR8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Operand >=3D 0) && (Operand <=3D MAX_INT8)) { + *Result =3D (CHAR8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D CHAR8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INTN -> UINT8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Operand >=3D 0) && (Operand <=3D MAX_UINT8)) { + *Result =3D (UINT8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INTN -> INT16 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Operand >=3D MIN_INT16) && (Operand <=3D MAX_INT16)) { + *Result =3D (INT16)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INT16_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INTN -> UINT16 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Operand >=3D 0) && (Operand <=3D MAX_UINT16)) { + *Result =3D (UINT16)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT16_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INTN -> UINTN conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand >=3D 0) { + *Result =3D (UINTN)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINTN_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INTN -> UINT64 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand >=3D 0) { + *Result =3D (UINT64)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT64_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINTN -> INT8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_INT8) { + *Result =3D (INT8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INT8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINTN -> CHAR8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_INT8) { + *Result =3D (INT8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D CHAR8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINTN -> UINT8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_UINT8) { + *Result =3D (UINT8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINTN -> INT16 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_INT16) { + *Result =3D (INT16)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INT16_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINTN -> UINT16 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_UINT16) { + *Result =3D (UINT16)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT16_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINTN -> INT32 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_INT32) { + *Result =3D (INT32)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INT32_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINTN -> INTN conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_INTN) { + *Result =3D (INTN)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INTN_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT64 -> INT8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Operand >=3D MIN_INT8) && (Operand <=3D MAX_INT8)) { + *Result =3D (INT8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INT8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT64 -> CHAR8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Operand >=3D 0) && (Operand <=3D MAX_INT8)) { + *Result =3D (CHAR8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D CHAR8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT64 -> UINT8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Operand >=3D 0) && (Operand <=3D MAX_UINT8)) { + *Result =3D (UINT8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT64 -> INT16 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Operand >=3D MIN_INT16) && (Operand <=3D MAX_INT16)) { + *Result =3D (INT16)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INT16_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT64 -> UINT16 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Operand >=3D 0) && (Operand <=3D MAX_UINT16)) { + *Result =3D (UINT16)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT16_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT64 -> INT32 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Operand >=3D MIN_INT32) && (Operand <=3D MAX_INT32)) { + *Result =3D (INT32)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INT32_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT64 -> UINT32 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Operand >=3D 0) && (Operand <=3D MAX_UINT32)) { + *Result =3D (UINT32)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT32_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + INT64 -> UINT64 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand >=3D 0) { + *Result =3D (UINT64)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT64_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINT64 -> INT8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_INT8) { + *Result =3D (INT8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INT8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINT64 -> CHAR8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_INT8) { + *Result =3D (INT8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D CHAR8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINT64 -> UINT8 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_UINT8) { + *Result =3D (UINT8)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT8_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINT64 -> INT16 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_INT16) { + *Result =3D (INT16)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INT16_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINT64 -> UINT16 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_UINT16) { + *Result =3D (UINT16)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT16_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINT64 -> INT32 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_INT32) { + *Result =3D (INT32)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INT32_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINT64 -> UINT32 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_UINT32) { + *Result =3D (UINT32)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT32_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINT64 -> INTN conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_INTN) { + *Result =3D (INTN)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INTN_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINT64 -> INT64 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand <=3D MAX_INT64) { + *Result =3D (INT64)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D INT64_ERROR; + Status =3D 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 condit= ion, + then Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (((UINT8)(Augend + Addend)) >=3D Augend) { + *Result =3D (UINT8)(Augend + Addend); + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT8_ERROR; + Status =3D 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 condit= ion, + then Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is return= ed. + + @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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (((UINT16)(Augend + Addend)) >=3D Augend) { + *Result =3D (UINT16)(Augend + Addend); + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT16_ERROR; + Status =3D 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 condit= ion, + then Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is return= ed. + + @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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Augend + Addend) >=3D Augend) { + *Result =3D (Augend + Addend); + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT32_ERROR; + Status =3D 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 condit= ion, + then Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is return= ed. + + @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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Augend + Addend) >=3D Augend) { + *Result =3D (Augend + Addend); + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT64_ERROR; + Status =3D 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 condit= ion, + then Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Minuend >=3D Subtrahend) { + *Result =3D (UINT8)(Minuend - Subtrahend); + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT8_ERROR; + Status =3D 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 condit= ion, + then Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is return= ed. + + @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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Minuend >=3D Subtrahend) { + *Result =3D (UINT16)(Minuend - Subtrahend); + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT16_ERROR; + Status =3D 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 condit= ion, + then Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is return= ed. + + @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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Minuend >=3D Subtrahend) { + *Result =3D (Minuend - Subtrahend); + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT32_ERROR; + Status =3D 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 condit= ion, + then Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is return= ed. + + @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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Minuend >=3D Subtrahend) { + *Result =3D (Minuend - Subtrahend); + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT64_ERROR; + Status =3D 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 condit= ion, + then Result is set to UINT8_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @param[in] Multiplicand A number that is to be multiplied by another + @param[in] Multiplier A number by which the multiplicand is to be m= ultiplied + @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 =3D ((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 condit= ion, + then Result is set to UINT16_ERROR and RETURN_BUFFER_TOO_SMALL is return= ed. + + @param[in] Multiplicand A number that is to be multiplied by another + @param[in] Multiplier A number by which the multiplicand is to be m= ultiplied + @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 =3D ((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 condit= ion, + then Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is return= ed. + + @param[in] Multiplicand A number that is to be multiplied by another + @param[in] Multiplier A number by which the multiplicand is to be m= ultiplied + @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 =3D ((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 condit= ion, + then Result is set to UINT64_ERROR and RETURN_BUFFER_TOO_SMALL is return= ed. + + @param[in] Multiplicand A number that is to be multiplied by another + @param[in] Multiplier A number by which the multiplicand is to be m= ultiplied + @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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + ProductAD =3D 0; + ProductBC =3D 0; + ProductBD =3D 0; + UnsignedResult =3D 0; + Status =3D RETURN_BUFFER_TOO_SMALL; + + // + // 64x64 into 128 is like 32.32 x 32.32. + // + // a.b * c.d =3D a*(c.d) + .b*(c.d) =3D a*c + a*.d + .b*c + .b*.d + // back in non-decimal notation where A=3Da*2^32 and C=3Dc*2^32: + // A*C + A*d + b*C + b*d + // So there are four components to add together. + // result =3D (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-bi= ts + // b * c must be less than 2^32 or there would be bits in the high 64-bi= ts + // then there must be no overflow of the resulting values summed up. + // + DwordA =3D (UINT32)(Multiplicand >> 32); + DwordC =3D (UINT32)(Multiplier >> 32); + + // + // common case -- if high dwords are both zero, no chance for overflow + // + if ((DwordA =3D=3D 0) && (DwordC =3D=3D 0)) { + DwordB =3D (UINT32)Multiplicand; + DwordD =3D (UINT32)Multiplier; + + *Result =3D (((UINT64)DwordB) *(UINT64)DwordD); + Status =3D RETURN_SUCCESS; + } else { + // + // a * c must be 0 or there would be bits set in the high 64-bits + // + if ((DwordA =3D=3D 0) || + (DwordC =3D=3D 0)) { + DwordD =3D (UINT32)Multiplier; + + // + // a * d must be less than 2^32 or there would be bits set in the hi= gh 64-bits + // + ProductAD =3D (((UINT64)DwordA) *(UINT64)DwordD); + if ((ProductAD & 0xffffffff00000000) =3D=3D 0) { + DwordB =3D (UINT32)Multiplicand; + + // + // b * c must be less than 2^32 or there would be bits set in the = high 64-bits + // + ProductBC =3D (((UINT64)DwordB) *(UINT64)DwordC); + if ((ProductBC & 0xffffffff00000000) =3D=3D 0) { + // + // now sum them all up checking for overflow. + // shifting is safe because we already checked for overflow abov= e + // + if (!RETURN_ERROR (SafeUint64Add (ProductBC << 32, ProductAD << = 32, &UnsignedResult))) { + // + // b * d + // + ProductBD =3D (((UINT64)DwordB) *(UINT64)DwordD); + + if (!RETURN_ERROR (SafeUint64Add (UnsignedResult, ProductBD, &= UnsignedResult))) { + *Result =3D UnsignedResult; + Status =3D RETURN_SUCCESS; + } + } + } + } + } + } + + if (RETURN_ERROR (Status)) { + *Result =3D 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 numb= er, +// 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 you= r +// 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 condit= ion, + 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 condit= ion, + then Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + Augend32 =3D (INT32)Augend; + Addend32 =3D (INT32)Addend; + if (Augend32 < 0 || Augend32 > MAX_INT8) { + *Result =3D CHAR8_ERROR; + return RETURN_BUFFER_TOO_SMALL; + } + if (Addend32 < 0 || Addend32 > MAX_INT8) { + *Result =3D 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 condit= ion, + then Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 condit= ion, + then Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 condit= ion, + then Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + SignedResult =3D 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) =3D=3D (Addend < 0)) && + ((Augend < 0) !=3D (SignedResult < 0))) { + *Result =3D INT64_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } else { + *Result =3D SignedResult; + Status =3D 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 condit= ion, + 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 condit= ion, + then Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + Minuend32 =3D (INT32)Minuend; + Subtrahend32 =3D (INT32)Subtrahend; + if (Minuend32 < 0 || Minuend32 > MAX_INT8) { + *Result =3D CHAR8_ERROR; + return RETURN_BUFFER_TOO_SMALL; + } + if (Subtrahend32 < 0 || Subtrahend32 > MAX_INT8) { + *Result =3D 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 condit= ion, + then Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 condit= ion, + then Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 condit= ion, + then Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + SignedResult =3D 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) !=3D (Subtrahend < 0)) && + ((Minuend < 0) !=3D (SignedResult < 0))) { + *Result =3D INT64_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } else { + *Result =3D SignedResult; + Status =3D 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 condit= ion, + 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 m= ultiplied + @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), Resu= lt); +} + +/** + 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 condit= ion, + then Result is set to CHAR8_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @param[in] Multiplicand A number that is to be multiplied by another + @param[in] Multiplier A number by which the multiplicand is to be m= ultiplied + @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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + Multiplicand32 =3D (INT32)Multiplicand; + Multiplier32 =3D (INT32)Multiplier; + if (Multiplicand32 < 0 || Multiplicand32 > MAX_INT8) { + *Result =3D CHAR8_ERROR; + return RETURN_BUFFER_TOO_SMALL; + } + if (Multiplier32 < 0 || Multiplier32 > MAX_INT8) { + *Result =3D 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 condit= ion, + then Result is set to INT16_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @param[in] Multiplicand A number that is to be multiplied by another + @param[in] Multiplier A number by which the multiplicand is to be m= ultiplied + @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), Res= ult); +} + +/** + 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 condit= ion, + then Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @param[in] Multiplicand A number that is to be multiplied by another + @param[in] Multiplier A number by which the multiplicand is to be m= ultiplied + @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), Res= ult); +} + +/** + 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 condit= ion, + then Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @param[in] Multiplicand A number that is to be multiplied by another + @param[in] Multiplier A number by which the multiplicand is to be m= ultiplied + @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 =3D=3D 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 =3D ((UINT64)(- (Multiplicand + 1))) + 1; + } else { + UnsignedMultiplicand =3D (UINT64)Multiplicand; + } + + if (Multiplier < 0) { + // + // Avoid negating the most negative number. + // + UnsignedMultiplier =3D ((UINT64)(- (Multiplier + 1))) + 1; + } else { + UnsignedMultiplier =3D (UINT64)Multiplier; + } + + Status =3D SafeUint64Mult (UnsignedMultiplicand, UnsignedMultiplier, &Un= signedResult); + if (!RETURN_ERROR (Status)) { + if ((Multiplicand < 0) !=3D (Multiplier < 0)) { + if (UnsignedResult > MIN_INT64_MAGNITUDE) { + *Result =3D INT64_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } else { + *Result =3D - ((INT64)UnsignedResult); + } + } else { + if (UnsignedResult > MAX_INT64) { + *Result =3D INT64_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } else { + *Result =3D (INT64)UnsignedResult; + } + } + } else { + *Result =3D 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 durin= g + 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 m= et: + 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 not= ice, + this list of conditions and the following disclaimer in the documentatio= n + 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 IM= PLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE D= ISCLAIMED. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY= DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCL= UDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF= USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY TH= EORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEG= LIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN I= F + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +**/ + +#include +#include + +/** + INT32 -> UINTN conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + *Result =3D (INT32)Operand; + return RETURN_SUCCESS; +} + +/** + INTN -> UINT32 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Operand >=3D 0) { + *Result =3D (UINT32)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT32_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; +} + +/** + UINTN -> UINT32 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + *Result =3D (UINT32)Operand; + return RETURN_SUCCESS; +} + +/** + UINTN -> INT64 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + *Result =3D (INT64)Operand; + return RETURN_SUCCESS; +} + +/** + INT64 -> INTN conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 condit= ion, + then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if ((Augend + Addend) >=3D Augend) { + *Result =3D (Augend + Addend); + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINTN_ERROR; + Status =3D 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 condit= ion, + then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (Minuend >=3D Subtrahend) { + *Result =3D (Minuend - Subtrahend); + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINTN_ERROR; + Status =3D 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 condit= ion, + then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @param[in] Multiplicand A number that is to be multiplied by another + @param[in] Multiplier A number by which the multiplicand is to be m= ultiplied + @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 =3D ((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 condit= ion, + 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 condit= ion, + 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 condit= ion, + 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 m= ultiplied + @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), Resu= lt); +} + 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 durin= g + 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 m= et: + 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 not= ice, + this list of conditions and the following disclaimer in the documentatio= n + 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 IM= PLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE D= ISCLAIMED. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY= DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCL= UDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF= USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY TH= EORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEG= LIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN I= F + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +**/ + +#include +#include + +/** + INT32 -> UINTN conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + *Result =3D Operand; + return RETURN_SUCCESS; +} + +/** + INTN -> INT32 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + *Result =3D (INTN)Operand; + return RETURN_SUCCESS; +} + +/** + INT64 -> UINTN conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + *Result =3D 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 condit= ion, + then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 condit= ion, + then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 *)Res= ult); +} + +/** + 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 condit= ion, + then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @param[in] Multiplicand A number that is to be multiplied by another + @param[in] Multiplier A number by which the multiplicand is to be m= ultiplied + @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 condit= ion, + 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 condit= ion, + 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 condit= ion, + 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 m= ultiplied + @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 *)R= esult); +} + 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 durin= g + 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 m= et: + 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 not= ice, + this list of conditions and the following disclaimer in the documentatio= n + 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 IM= PLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE D= ISCLAIMED. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY= DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCL= UDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF= USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY TH= EORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEG= LIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN I= F + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +**/ + +#include +#include + +/** + INT32 -> UINTN conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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) =3D=3D 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (sizeof (UINTN) =3D=3D sizeof (UINT32)) { + return SafeUint32ToInt32 (Operand, (INT32 *)Result); + } + *Result =3D Operand; + return RETURN_SUCCESS; +} + +/** + INTN -> INT32 conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (sizeof (UINTN) =3D=3D sizeof (UINT32)) { + *Result =3D (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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (sizeof (UINTN) =3D=3D sizeof (UINT32)) { + if (Operand >=3D 0) { + *Result =3D (UINT32)Operand; + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINT32_ERROR; + Status =3D 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (sizeof (UINTN) =3D=3D sizeof (UINT32)) { + *Result =3D (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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (sizeof (UINTN) =3D=3D sizeof (UINT32)) { + *Result =3D (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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (sizeof (UINTN) =3D=3D sizeof (UINT32)) { + return SafeInt64ToInt32 (Operand, (INT32 *)Result); + } + *Result =3D (INTN)Operand; + return RETURN_SUCCESS; +} + +/** + INT64 -> UINTN conversion + + Converts the value specified by Operand to a value specified by Result t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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) =3D=3D 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 t= ype + and stores the converted value into the caller allocated output buffer + specified by Result. The caller must pass in a Result buffer that is at + least as large as the Result type. + + If 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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (sizeof (UINTN) =3D=3D sizeof (UINT32)) { + return SafeUint64ToUint32 ((UINT64) Operand, (UINT32 *)Result); + } + *Result =3D 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 condit= ion, + then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (sizeof (UINTN) =3D=3D sizeof (UINT32)) { + if ((UINT32)(Augend + Addend) >=3D Augend) { + *Result =3D (Augend + Addend); + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINTN_ERROR; + Status =3D 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 condit= ion, + then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @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 =3D=3D NULL) { + return RETURN_INVALID_PARAMETER; + } + + if (sizeof (UINTN) =3D=3D sizeof (UINT32)) { + if (Minuend >=3D Subtrahend) { + *Result =3D (Minuend - Subtrahend); + Status =3D RETURN_SUCCESS; + } else { + *Result =3D UINTN_ERROR; + Status =3D RETURN_BUFFER_TOO_SMALL; + } + + return Status; + } + return SafeUint64Sub ((UINT64)Minuend, (UINT64)Subtrahend, (UINT64 *)Res= ult); +} + +/** + 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 condit= ion, + then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returne= d. + + @param[in] Multiplicand A number that is to be multiplied by another + @param[in] Multiplier A number by which the multiplicand is to be m= ultiplied + @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) =3D=3D sizeof (UINT32)) { + IntermediateResult =3D ((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 condit= ion, + 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) =3D=3D 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 condit= ion, + 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) =3D=3D 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 condit= ion, + 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 m= ultiplied + @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) =3D=3D sizeof (UINT32)) { + return SafeInt64ToIntn (((INT64)Multiplicand) *((INT64)Multiplier), Re= sult); + } + return SafeInt64Mult ((INT64)Multiplicand, (INT64)Multiplier, (INT64 *)R= esult); +} + 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 d= uring + # type conversion, addition, subtraction, and multiplicat= ion. + ## + 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