MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance
https://bugzilla.tianocore.org/show_bug.cgi?id=798
SafeIntLib provides helper functions to prevent integer overflow
during type conversion, addition, subtraction, and multiplication.
Conversion Functions
====================
* Converting from a signed type to an unsigned type of the same
size, or vice-versa.
* Converting to a smaller type that could possibly overflow.
* Converting from a signed type to a larger unsigned type.
Unsigned Addition, Subtraction, Multiplication
===============================================
* Unsigned integer math functions protect from overflow and
underflow (in case of subtraction).
Signed Addition, Subtraction, Multiplication
============================================
* Strongly consider using unsigned numbers.
* Signed numbers are often used where unsigned numbers should
be used. For example file sizes and array indices should always
be unsigned. Subtracting a larger positive signed number from a
smaller positive signed number with SafeInt32Sub() will succeed,
producing a negative number, that then must not be used as an
array index (but can occasionally be used as a pointer index.)
Similarly for adding a larger magnitude negative number to a
smaller magnitude positive number.
* SafeIntLib does not protect you from such errors. It tells you
if your integer operations overflowed, not if you are doing the
right thing with your non-overflowed integers.
* Likewise you can overflow a buffer with a non-overflowed
unsigned index.
Based on content from the following branch/commits:
https://github.com/Microsoft/MS_UEFI/tree/share/MsCapsuleSupport
https://github.com/Microsoft/MS_UEFI/commit/21ef3a321c907b40fa93797619c9f6c686dd92e0
https://github.com/Microsoft/MS_UEFI/commit/ca516b1a61315c2d823f453e12d2135098f53d61
https://github.com/Microsoft/MS_UEFI/commit/33bab4031a417d7d5a7d356c15a14c2e60302b2d
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Sean Brogan <sean.brogan@microsoft.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
2017-04-25 01:37:20 +02:00
|
|
|
/** @file
|
|
|
|
This library provides helper functions to prevent integer overflow during
|
|
|
|
type conversion, addition, subtraction, and multiplication.
|
|
|
|
|
|
|
|
Copyright (c) 2017, Microsoft Corporation
|
|
|
|
|
|
|
|
All rights reserved.
|
2019-04-04 01:06:00 +02:00
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
MdePkg/BaseSafeIntLib: Add SafeIntLib class and instance
https://bugzilla.tianocore.org/show_bug.cgi?id=798
SafeIntLib provides helper functions to prevent integer overflow
during type conversion, addition, subtraction, and multiplication.
Conversion Functions
====================
* Converting from a signed type to an unsigned type of the same
size, or vice-versa.
* Converting to a smaller type that could possibly overflow.
* Converting from a signed type to a larger unsigned type.
Unsigned Addition, Subtraction, Multiplication
===============================================
* Unsigned integer math functions protect from overflow and
underflow (in case of subtraction).
Signed Addition, Subtraction, Multiplication
============================================
* Strongly consider using unsigned numbers.
* Signed numbers are often used where unsigned numbers should
be used. For example file sizes and array indices should always
be unsigned. Subtracting a larger positive signed number from a
smaller positive signed number with SafeInt32Sub() will succeed,
producing a negative number, that then must not be used as an
array index (but can occasionally be used as a pointer index.)
Similarly for adding a larger magnitude negative number to a
smaller magnitude positive number.
* SafeIntLib does not protect you from such errors. It tells you
if your integer operations overflowed, not if you are doing the
right thing with your non-overflowed integers.
* Likewise you can overflow a buffer with a non-overflowed
unsigned index.
Based on content from the following branch/commits:
https://github.com/Microsoft/MS_UEFI/tree/share/MsCapsuleSupport
https://github.com/Microsoft/MS_UEFI/commit/21ef3a321c907b40fa93797619c9f6c686dd92e0
https://github.com/Microsoft/MS_UEFI/commit/ca516b1a61315c2d823f453e12d2135098f53d61
https://github.com/Microsoft/MS_UEFI/commit/33bab4031a417d7d5a7d356c15a14c2e60302b2d
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Sean Brogan <sean.brogan@microsoft.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
2017-04-25 01:37:20 +02:00
|
|
|
|
|
|
|
**/
|
|
|
|
|
|
|
|
#include <Base.h>
|
|
|
|
#include <Library/SafeIntLib.h>
|
|
|
|
|
|
|
|
/**
|
|
|
|
INT32 -> UINTN conversion
|
|
|
|
|
|
|
|
Converts the value specified by Operand to a value specified by Result type
|
|
|
|
and stores the converted value into the caller allocated output buffer
|
|
|
|
specified by Result. The caller must pass in a Result buffer that is at
|
|
|
|
least as large as the Result type.
|
|
|
|
|
|
|
|
If Result is NULL, RETURN_INVALID_PARAMETER is returned.
|
|
|
|
|
|
|
|
If the conversion results in an overflow or an underflow condition, then
|
|
|
|
Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
|
|
|
|
|
|
|
|
@param[in] Operand Operand to be converted to new type
|
|
|
|
@param[out] Result Pointer to the result of conversion
|
|
|
|
|
|
|
|
@retval RETURN_SUCCESS Successful conversion
|
|
|
|
@retval RETURN_BUFFER_TOO_SMALL Overflow
|
|
|
|
@retval RETURN_INVALID_PARAMETER Result is NULL
|
|
|
|
**/
|
|
|
|
RETURN_STATUS
|
|
|
|
EFIAPI
|
|
|
|
SafeInt32ToUintn (
|
|
|
|
IN INT32 Operand,
|
|
|
|
OUT UINTN *Result
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (sizeof (UINTN) == sizeof (UINT32)) {
|
|
|
|
return SafeInt32ToUint32 (Operand, (UINT32 *)Result);
|
|
|
|
}
|
|
|
|
return SafeInt32ToUint64 (Operand, (UINT64 *) Result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
UINT32 -> INTN conversion
|
|
|
|
|
|
|
|
Converts the value specified by Operand to a value specified by Result type
|
|
|
|
and stores the converted value into the caller allocated output buffer
|
|
|
|
specified by Result. The caller must pass in a Result buffer that is at
|
|
|
|
least as large as the Result type.
|
|
|
|
|
|
|
|
If Result is NULL, RETURN_INVALID_PARAMETER is returned.
|
|
|
|
|
|
|
|
If the conversion results in an overflow or an underflow condition, then
|
|
|
|
Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
|
|
|
|
|
|
|
|
@param[in] Operand Operand to be converted to new type
|
|
|
|
@param[out] Result Pointer to the result of conversion
|
|
|
|
|
|
|
|
@retval RETURN_SUCCESS Successful conversion
|
|
|
|
@retval RETURN_BUFFER_TOO_SMALL Overflow
|
|
|
|
@retval RETURN_INVALID_PARAMETER Result is NULL
|
|
|
|
**/
|
|
|
|
RETURN_STATUS
|
|
|
|
EFIAPI
|
|
|
|
SafeUint32ToIntn (
|
|
|
|
IN UINT32 Operand,
|
|
|
|
OUT INTN *Result
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (Result == NULL) {
|
|
|
|
return RETURN_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sizeof (UINTN) == sizeof (UINT32)) {
|
|
|
|
return SafeUint32ToInt32 (Operand, (INT32 *)Result);
|
|
|
|
}
|
|
|
|
*Result = Operand;
|
|
|
|
return RETURN_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
INTN -> INT32 conversion
|
|
|
|
|
|
|
|
Converts the value specified by Operand to a value specified by Result type
|
|
|
|
and stores the converted value into the caller allocated output buffer
|
|
|
|
specified by Result. The caller must pass in a Result buffer that is at
|
|
|
|
least as large as the Result type.
|
|
|
|
|
|
|
|
If Result is NULL, RETURN_INVALID_PARAMETER is returned.
|
|
|
|
|
|
|
|
If the conversion results in an overflow or an underflow condition, then
|
|
|
|
Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
|
|
|
|
|
|
|
|
@param[in] Operand Operand to be converted to new type
|
|
|
|
@param[out] Result Pointer to the result of conversion
|
|
|
|
|
|
|
|
@retval RETURN_SUCCESS Successful conversion
|
|
|
|
@retval RETURN_BUFFER_TOO_SMALL Overflow
|
|
|
|
@retval RETURN_INVALID_PARAMETER Result is NULL
|
|
|
|
**/
|
|
|
|
RETURN_STATUS
|
|
|
|
EFIAPI
|
|
|
|
SafeIntnToInt32 (
|
|
|
|
IN INTN Operand,
|
|
|
|
OUT INT32 *Result
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (Result == NULL) {
|
|
|
|
return RETURN_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sizeof (UINTN) == sizeof (UINT32)) {
|
|
|
|
*Result = (INT32)Operand;
|
|
|
|
return RETURN_SUCCESS;
|
|
|
|
}
|
|
|
|
return SafeInt64ToInt32 ((INT64) Operand, Result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
INTN -> UINT32 conversion
|
|
|
|
|
|
|
|
Converts the value specified by Operand to a value specified by Result type
|
|
|
|
and stores the converted value into the caller allocated output buffer
|
|
|
|
specified by Result. The caller must pass in a Result buffer that is at
|
|
|
|
least as large as the Result type.
|
|
|
|
|
|
|
|
If Result is NULL, RETURN_INVALID_PARAMETER is returned.
|
|
|
|
|
|
|
|
If the conversion results in an overflow or an underflow condition, then
|
|
|
|
Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
|
|
|
|
|
|
|
|
@param[in] Operand Operand to be converted to new type
|
|
|
|
@param[out] Result Pointer to the result of conversion
|
|
|
|
|
|
|
|
@retval RETURN_SUCCESS Successful conversion
|
|
|
|
@retval RETURN_BUFFER_TOO_SMALL Overflow
|
|
|
|
@retval RETURN_INVALID_PARAMETER Result is NULL
|
|
|
|
**/
|
|
|
|
RETURN_STATUS
|
|
|
|
EFIAPI
|
|
|
|
SafeIntnToUint32 (
|
|
|
|
IN INTN Operand,
|
|
|
|
OUT UINT32 *Result
|
|
|
|
)
|
|
|
|
{
|
|
|
|
RETURN_STATUS Status;
|
|
|
|
|
|
|
|
if (Result == NULL) {
|
|
|
|
return RETURN_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sizeof (UINTN) == sizeof (UINT32)) {
|
|
|
|
if (Operand >= 0) {
|
|
|
|
*Result = (UINT32)Operand;
|
|
|
|
Status = RETURN_SUCCESS;
|
|
|
|
} else {
|
|
|
|
*Result = UINT32_ERROR;
|
|
|
|
Status = RETURN_BUFFER_TOO_SMALL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
return SafeInt64ToUint32 ((INT64)Operand, Result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
UINTN -> UINT32 conversion
|
|
|
|
|
|
|
|
Converts the value specified by Operand to a value specified by Result type
|
|
|
|
and stores the converted value into the caller allocated output buffer
|
|
|
|
specified by Result. The caller must pass in a Result buffer that is at
|
|
|
|
least as large as the Result type.
|
|
|
|
|
|
|
|
If Result is NULL, RETURN_INVALID_PARAMETER is returned.
|
|
|
|
|
|
|
|
If the conversion results in an overflow or an underflow condition, then
|
|
|
|
Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
|
|
|
|
|
|
|
|
@param[in] Operand Operand to be converted to new type
|
|
|
|
@param[out] Result Pointer to the result of conversion
|
|
|
|
|
|
|
|
@retval RETURN_SUCCESS Successful conversion
|
|
|
|
@retval RETURN_BUFFER_TOO_SMALL Overflow
|
|
|
|
@retval RETURN_INVALID_PARAMETER Result is NULL
|
|
|
|
**/
|
|
|
|
RETURN_STATUS
|
|
|
|
EFIAPI
|
|
|
|
SafeUintnToUint32 (
|
|
|
|
IN UINTN Operand,
|
|
|
|
OUT UINT32 *Result
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (Result == NULL) {
|
|
|
|
return RETURN_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sizeof (UINTN) == sizeof (UINT32)) {
|
|
|
|
*Result = (UINT32)Operand;
|
|
|
|
return RETURN_SUCCESS;
|
|
|
|
}
|
|
|
|
return SafeUint64ToUint32 ((UINT64)Operand, Result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
UINTN -> INT64 conversion
|
|
|
|
|
|
|
|
Converts the value specified by Operand to a value specified by Result type
|
|
|
|
and stores the converted value into the caller allocated output buffer
|
|
|
|
specified by Result. The caller must pass in a Result buffer that is at
|
|
|
|
least as large as the Result type.
|
|
|
|
|
|
|
|
If Result is NULL, RETURN_INVALID_PARAMETER is returned.
|
|
|
|
|
|
|
|
If the conversion results in an overflow or an underflow condition, then
|
|
|
|
Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
|
|
|
|
|
|
|
|
@param[in] Operand Operand to be converted to new type
|
|
|
|
@param[out] Result Pointer to the result of conversion
|
|
|
|
|
|
|
|
@retval RETURN_SUCCESS Successful conversion
|
|
|
|
@retval RETURN_BUFFER_TOO_SMALL Overflow
|
|
|
|
@retval RETURN_INVALID_PARAMETER Result is NULL
|
|
|
|
**/
|
|
|
|
RETURN_STATUS
|
|
|
|
EFIAPI
|
|
|
|
SafeUintnToInt64 (
|
|
|
|
IN UINTN Operand,
|
|
|
|
OUT INT64 *Result
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (Result == NULL) {
|
|
|
|
return RETURN_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sizeof (UINTN) == sizeof (UINT32)) {
|
|
|
|
*Result = (INT64)Operand;
|
|
|
|
return RETURN_SUCCESS;
|
|
|
|
}
|
|
|
|
return SafeUint64ToInt64 ((UINT64)Operand, Result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
INT64 -> INTN conversion
|
|
|
|
|
|
|
|
Converts the value specified by Operand to a value specified by Result type
|
|
|
|
and stores the converted value into the caller allocated output buffer
|
|
|
|
specified by Result. The caller must pass in a Result buffer that is at
|
|
|
|
least as large as the Result type.
|
|
|
|
|
|
|
|
If Result is NULL, RETURN_INVALID_PARAMETER is returned.
|
|
|
|
|
|
|
|
If the conversion results in an overflow or an underflow condition, then
|
|
|
|
Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
|
|
|
|
|
|
|
|
@param[in] Operand Operand to be converted to new type
|
|
|
|
@param[out] Result Pointer to the result of conversion
|
|
|
|
|
|
|
|
@retval RETURN_SUCCESS Successful conversion
|
|
|
|
@retval RETURN_BUFFER_TOO_SMALL Overflow
|
|
|
|
@retval RETURN_INVALID_PARAMETER Result is NULL
|
|
|
|
**/
|
|
|
|
RETURN_STATUS
|
|
|
|
EFIAPI
|
|
|
|
SafeInt64ToIntn (
|
|
|
|
IN INT64 Operand,
|
|
|
|
OUT INTN *Result
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (Result == NULL) {
|
|
|
|
return RETURN_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sizeof (UINTN) == sizeof (UINT32)) {
|
|
|
|
return SafeInt64ToInt32 (Operand, (INT32 *)Result);
|
|
|
|
}
|
|
|
|
*Result = (INTN)Operand;
|
|
|
|
return RETURN_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
INT64 -> UINTN conversion
|
|
|
|
|
|
|
|
Converts the value specified by Operand to a value specified by Result type
|
|
|
|
and stores the converted value into the caller allocated output buffer
|
|
|
|
specified by Result. The caller must pass in a Result buffer that is at
|
|
|
|
least as large as the Result type.
|
|
|
|
|
|
|
|
If Result is NULL, RETURN_INVALID_PARAMETER is returned.
|
|
|
|
|
|
|
|
If the conversion results in an overflow or an underflow condition, then
|
|
|
|
Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
|
|
|
|
|
|
|
|
@param[in] Operand Operand to be converted to new type
|
|
|
|
@param[out] Result Pointer to the result of conversion
|
|
|
|
|
|
|
|
@retval RETURN_SUCCESS Successful conversion
|
|
|
|
@retval RETURN_BUFFER_TOO_SMALL Overflow
|
|
|
|
@retval RETURN_INVALID_PARAMETER Result is NULL
|
|
|
|
**/
|
|
|
|
RETURN_STATUS
|
|
|
|
EFIAPI
|
|
|
|
SafeInt64ToUintn (
|
|
|
|
IN INT64 Operand,
|
|
|
|
OUT UINTN *Result
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (sizeof (UINTN) == sizeof (UINT32)) {
|
|
|
|
return SafeInt64ToUint32 (Operand, (UINT32 *)Result);
|
|
|
|
}
|
|
|
|
return SafeInt64ToUint64 (Operand, (UINT64 *)Result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
UINT64 -> UINTN conversion
|
|
|
|
|
|
|
|
Converts the value specified by Operand to a value specified by Result type
|
|
|
|
and stores the converted value into the caller allocated output buffer
|
|
|
|
specified by Result. The caller must pass in a Result buffer that is at
|
|
|
|
least as large as the Result type.
|
|
|
|
|
|
|
|
If Result is NULL, RETURN_INVALID_PARAMETER is returned.
|
|
|
|
|
|
|
|
If the conversion results in an overflow or an underflow condition, then
|
|
|
|
Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
|
|
|
|
|
|
|
|
@param[in] Operand Operand to be converted to new type
|
|
|
|
@param[out] Result Pointer to the result of conversion
|
|
|
|
|
|
|
|
@retval RETURN_SUCCESS Successful conversion
|
|
|
|
@retval RETURN_BUFFER_TOO_SMALL Overflow
|
|
|
|
@retval RETURN_INVALID_PARAMETER Result is NULL
|
|
|
|
**/
|
|
|
|
RETURN_STATUS
|
|
|
|
EFIAPI
|
|
|
|
SafeUint64ToUintn (
|
|
|
|
IN UINT64 Operand,
|
|
|
|
OUT UINTN *Result
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (Result == NULL) {
|
|
|
|
return RETURN_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sizeof (UINTN) == sizeof (UINT32)) {
|
|
|
|
return SafeUint64ToUint32 ((UINT64) Operand, (UINT32 *)Result);
|
|
|
|
}
|
|
|
|
*Result = Operand;
|
|
|
|
return RETURN_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
UINTN addition
|
|
|
|
|
|
|
|
Performs the requested operation using the input parameters into a value
|
|
|
|
specified by Result type and stores the converted value into the caller
|
|
|
|
allocated output buffer specified by Result. The caller must pass in a
|
|
|
|
Result buffer that is at least as large as the Result type.
|
|
|
|
|
|
|
|
If Result is NULL, RETURN_INVALID_PARAMETER is returned.
|
|
|
|
|
|
|
|
If the requested operation results in an overflow or an underflow condition,
|
|
|
|
then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
|
|
|
|
|
|
|
|
@param[in] Augend A number to which addend will be added
|
|
|
|
@param[in] Addend A number to be added to another
|
|
|
|
@param[out] Result Pointer to the result of addition
|
|
|
|
|
|
|
|
@retval RETURN_SUCCESS Successful addition
|
|
|
|
@retval RETURN_BUFFER_TOO_SMALL Overflow
|
|
|
|
@retval RETURN_INVALID_PARAMETER Result is NULL
|
|
|
|
**/
|
|
|
|
RETURN_STATUS
|
|
|
|
EFIAPI
|
|
|
|
SafeUintnAdd (
|
|
|
|
IN UINTN Augend,
|
|
|
|
IN UINTN Addend,
|
|
|
|
OUT UINTN *Result
|
|
|
|
)
|
|
|
|
{
|
|
|
|
RETURN_STATUS Status;
|
|
|
|
|
|
|
|
if (Result == NULL) {
|
|
|
|
return RETURN_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sizeof (UINTN) == sizeof (UINT32)) {
|
|
|
|
if ((UINT32)(Augend + Addend) >= Augend) {
|
|
|
|
*Result = (Augend + Addend);
|
|
|
|
Status = RETURN_SUCCESS;
|
|
|
|
} else {
|
|
|
|
*Result = UINTN_ERROR;
|
|
|
|
Status = RETURN_BUFFER_TOO_SMALL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
return SafeUint64Add ((UINT64)Augend, (UINT64)Addend, (UINT64 *)Result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
UINTN subtraction
|
|
|
|
|
|
|
|
Performs the requested operation using the input parameters into a value
|
|
|
|
specified by Result type and stores the converted value into the caller
|
|
|
|
allocated output buffer specified by Result. The caller must pass in a
|
|
|
|
Result buffer that is at least as large as the Result type.
|
|
|
|
|
|
|
|
If Result is NULL, RETURN_INVALID_PARAMETER is returned.
|
|
|
|
|
|
|
|
If the requested operation results in an overflow or an underflow condition,
|
|
|
|
then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
|
|
|
|
|
|
|
|
@param[in] Minuend A number from which another is to be subtracted.
|
|
|
|
@param[in] Subtrahend A number to be subtracted from another
|
|
|
|
@param[out] Result Pointer to the result of subtraction
|
|
|
|
|
|
|
|
@retval RETURN_SUCCESS Successful subtraction
|
|
|
|
@retval RETURN_BUFFER_TOO_SMALL Underflow
|
|
|
|
@retval RETURN_INVALID_PARAMETER Result is NULL
|
|
|
|
**/
|
|
|
|
RETURN_STATUS
|
|
|
|
EFIAPI
|
|
|
|
SafeUintnSub (
|
|
|
|
IN UINTN Minuend,
|
|
|
|
IN UINTN Subtrahend,
|
|
|
|
OUT UINTN *Result
|
|
|
|
)
|
|
|
|
{
|
|
|
|
RETURN_STATUS Status;
|
|
|
|
|
|
|
|
if (Result == NULL) {
|
|
|
|
return RETURN_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sizeof (UINTN) == sizeof (UINT32)) {
|
|
|
|
if (Minuend >= Subtrahend) {
|
|
|
|
*Result = (Minuend - Subtrahend);
|
|
|
|
Status = RETURN_SUCCESS;
|
|
|
|
} else {
|
|
|
|
*Result = UINTN_ERROR;
|
|
|
|
Status = RETURN_BUFFER_TOO_SMALL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
return SafeUint64Sub ((UINT64)Minuend, (UINT64)Subtrahend, (UINT64 *)Result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
UINTN multiplication
|
|
|
|
|
|
|
|
Performs the requested operation using the input parameters into a value
|
|
|
|
specified by Result type and stores the converted value into the caller
|
|
|
|
allocated output buffer specified by Result. The caller must pass in a
|
|
|
|
Result buffer that is at least as large as the Result type.
|
|
|
|
|
|
|
|
If Result is NULL, RETURN_INVALID_PARAMETER is returned.
|
|
|
|
|
|
|
|
If the requested operation results in an overflow or an underflow condition,
|
|
|
|
then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
|
|
|
|
|
|
|
|
@param[in] Multiplicand A number that is to be multiplied by another
|
|
|
|
@param[in] Multiplier A number by which the multiplicand is to be multiplied
|
|
|
|
@param[out] Result Pointer to the result of multiplication
|
|
|
|
|
|
|
|
@retval RETURN_SUCCESS Successful multiplication
|
|
|
|
@retval RETURN_BUFFER_TOO_SMALL Overflow
|
|
|
|
@retval RETURN_INVALID_PARAMETER Result is NULL
|
|
|
|
**/
|
|
|
|
RETURN_STATUS
|
|
|
|
EFIAPI
|
|
|
|
SafeUintnMult (
|
|
|
|
IN UINTN Multiplicand,
|
|
|
|
IN UINTN Multiplier,
|
|
|
|
OUT UINTN *Result
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINT64 IntermediateResult;
|
|
|
|
|
|
|
|
if (sizeof (UINTN) == sizeof (UINT32)) {
|
|
|
|
IntermediateResult = ((UINT64) Multiplicand) *((UINT64) Multiplier);
|
|
|
|
|
|
|
|
return SafeUint64ToUintn (IntermediateResult, Result);
|
|
|
|
}
|
|
|
|
return SafeUint64Mult ((UINT64)Multiplicand, (UINT64)Multiplier, (UINT64 *)Result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
INTN Addition
|
|
|
|
|
|
|
|
Performs the requested operation using the input parameters into a value
|
|
|
|
specified by Result type and stores the converted value into the caller
|
|
|
|
allocated output buffer specified by Result. The caller must pass in a
|
|
|
|
Result buffer that is at least as large as the Result type.
|
|
|
|
|
|
|
|
If Result is NULL, RETURN_INVALID_PARAMETER is returned.
|
|
|
|
|
|
|
|
If the requested operation results in an overflow or an underflow condition,
|
|
|
|
then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
|
|
|
|
|
|
|
|
@param[in] Augend A number to which addend will be added
|
|
|
|
@param[in] Addend A number to be added to another
|
|
|
|
@param[out] Result Pointer to the result of addition
|
|
|
|
|
|
|
|
@retval RETURN_SUCCESS Successful addition
|
|
|
|
@retval RETURN_BUFFER_TOO_SMALL Overflow
|
|
|
|
@retval RETURN_INVALID_PARAMETER Result is NULL
|
|
|
|
**/
|
|
|
|
RETURN_STATUS
|
|
|
|
EFIAPI
|
|
|
|
SafeIntnAdd (
|
|
|
|
IN INTN Augend,
|
|
|
|
IN INTN Addend,
|
|
|
|
OUT INTN *Result
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (sizeof (UINTN) == sizeof (UINT32)) {
|
|
|
|
return SafeInt64ToIntn (((INT64)Augend) + ((INT64)Addend), Result);
|
|
|
|
}
|
|
|
|
return SafeInt64Add ((INT64)Augend, (INT64)Addend, (INT64 *)Result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
INTN Subtraction
|
|
|
|
|
|
|
|
Performs the requested operation using the input parameters into a value
|
|
|
|
specified by Result type and stores the converted value into the caller
|
|
|
|
allocated output buffer specified by Result. The caller must pass in a
|
|
|
|
Result buffer that is at least as large as the Result type.
|
|
|
|
|
|
|
|
If Result is NULL, RETURN_INVALID_PARAMETER is returned.
|
|
|
|
|
|
|
|
If the requested operation results in an overflow or an underflow condition,
|
|
|
|
then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
|
|
|
|
|
|
|
|
@param[in] Minuend A number from which another is to be subtracted.
|
|
|
|
@param[in] Subtrahend A number to be subtracted from another
|
|
|
|
@param[out] Result Pointer to the result of subtraction
|
|
|
|
|
|
|
|
@retval RETURN_SUCCESS Successful subtraction
|
|
|
|
@retval RETURN_BUFFER_TOO_SMALL Underflow
|
|
|
|
@retval RETURN_INVALID_PARAMETER Result is NULL
|
|
|
|
**/
|
|
|
|
RETURN_STATUS
|
|
|
|
EFIAPI
|
|
|
|
SafeIntnSub (
|
|
|
|
IN INTN Minuend,
|
|
|
|
IN INTN Subtrahend,
|
|
|
|
OUT INTN *Result
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (sizeof (UINTN) == sizeof (UINT32)) {
|
|
|
|
return SafeInt64ToIntn (((INT64)Minuend) - ((INT64)Subtrahend), Result);
|
|
|
|
}
|
|
|
|
return SafeInt64Sub ((INT64)Minuend, (INT64)Subtrahend, (INT64 *)Result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
INTN multiplication
|
|
|
|
|
|
|
|
Performs the requested operation using the input parameters into a value
|
|
|
|
specified by Result type and stores the converted value into the caller
|
|
|
|
allocated output buffer specified by Result. The caller must pass in a
|
|
|
|
Result buffer that is at least as large as the Result type.
|
|
|
|
|
|
|
|
If Result is NULL, RETURN_INVALID_PARAMETER is returned.
|
|
|
|
|
|
|
|
If the requested operation results in an overflow or an underflow condition,
|
|
|
|
then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
|
|
|
|
|
|
|
|
@param[in] Multiplicand A number that is to be multiplied by another
|
|
|
|
@param[in] Multiplier A number by which the multiplicand is to be multiplied
|
|
|
|
@param[out] Result Pointer to the result of multiplication
|
|
|
|
|
|
|
|
@retval RETURN_SUCCESS Successful multiplication
|
|
|
|
@retval RETURN_BUFFER_TOO_SMALL Overflow
|
|
|
|
@retval RETURN_INVALID_PARAMETER Result is NULL
|
|
|
|
**/
|
|
|
|
RETURN_STATUS
|
|
|
|
EFIAPI
|
|
|
|
SafeIntnMult (
|
|
|
|
IN INTN Multiplicand,
|
|
|
|
IN INTN Multiplier,
|
|
|
|
OUT INTN *Result
|
|
|
|
)
|
|
|
|
{
|
|
|
|
if (sizeof (UINTN) == sizeof (UINT32)) {
|
|
|
|
return SafeInt64ToIntn (((INT64)Multiplicand) *((INT64)Multiplier), Result);
|
|
|
|
}
|
|
|
|
return SafeInt64Mult ((INT64)Multiplicand, (INT64)Multiplier, (INT64 *)Result);
|
|
|
|
}
|
|
|
|
|