2007-06-22 05:21:45 +02:00
|
|
|
/** @file
|
|
|
|
Utility functions to generate checksum based on 2's complement
|
|
|
|
algorithm.
|
|
|
|
|
|
|
|
Copyright (c) 2007, Intel Corporation<BR>
|
|
|
|
All rights reserved. This program and the accompanying materials
|
|
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
|
|
|
|
Module Name: CheckSum.c
|
|
|
|
|
|
|
|
**/
|
|
|
|
|
|
|
|
//
|
|
|
|
// Include common header file for this module.
|
|
|
|
//
|
2007-06-30 01:22:13 +02:00
|
|
|
#include <BaseLibInternals.h>
|
|
|
|
|
2007-06-22 05:21:45 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
Calculate the sum of all elements in a buffer in unit of UINT8.
|
|
|
|
During calculation, the carry bits are dropped.
|
|
|
|
|
|
|
|
This function calculates the sum of all elements in a buffer
|
|
|
|
in unit of UINT8. The carry bits in result of addition are dropped.
|
|
|
|
The result is returned as UINT8. If Length is Zero, then Zero is
|
|
|
|
returned.
|
|
|
|
|
|
|
|
If Buffer is NULL, then ASSERT().
|
|
|
|
If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
|
|
|
|
|
|
|
|
@param Buffer Pointer to the buffer to carry out the sum operation.
|
|
|
|
@param Length The size, in bytes, of Buffer .
|
|
|
|
|
|
|
|
@return Sum The sum of Buffer with carry bits dropped during additions.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINT8
|
|
|
|
EFIAPI
|
|
|
|
CalculateSum8 (
|
|
|
|
IN CONST UINT8 *Buffer,
|
|
|
|
IN UINTN Length
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINT8 Sum;
|
|
|
|
UINTN Count;
|
|
|
|
|
|
|
|
ASSERT (Buffer != NULL);
|
|
|
|
ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));
|
|
|
|
|
|
|
|
for (Sum = 0, Count = 0; Count < Length; Count++) {
|
|
|
|
Sum = (UINT8) (Sum + *(Buffer + Count));
|
|
|
|
}
|
|
|
|
|
|
|
|
return Sum;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Returns the two's complement checksum of all elements in a buffer
|
|
|
|
of 8-bit values.
|
|
|
|
|
|
|
|
This function first calculates the sum of the 8-bit values in the
|
|
|
|
buffer specified by Buffer and Length. The carry bits in the result
|
|
|
|
of addition are dropped. Then, the two's complement of the sum is
|
|
|
|
returned. If Length is 0, then 0 is returned.
|
|
|
|
|
|
|
|
If Buffer is NULL, then ASSERT().
|
|
|
|
If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
|
|
|
|
|
|
|
|
|
|
|
|
@param Buffer Pointer to the buffer to carry out the checksum operation.
|
|
|
|
@param Length The size, in bytes, of Buffer.
|
|
|
|
|
|
|
|
@return Checksum The 2's complement checksum of Buffer.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINT8
|
|
|
|
EFIAPI
|
|
|
|
CalculateCheckSum8 (
|
|
|
|
IN CONST UINT8 *Buffer,
|
|
|
|
IN UINTN Length
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINT8 CheckSum;
|
|
|
|
|
|
|
|
CheckSum = CalculateSum8 (Buffer, Length);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Return the checksum based on 2's complement.
|
|
|
|
//
|
|
|
|
return (UINT8) (0x100 - CheckSum);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Returns the sum of all elements in a buffer of 16-bit values. During
|
|
|
|
calculation, the carry bits are dropped.
|
|
|
|
|
|
|
|
This function calculates the sum of the 16-bit values in the buffer
|
|
|
|
specified by Buffer and Length. The carry bits in result of addition are dropped.
|
|
|
|
The 16-bit result is returned. If Length is 0, then 0 is returned.
|
|
|
|
|
|
|
|
If Buffer is NULL, then ASSERT().
|
|
|
|
If Buffer is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
If Length is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
|
|
|
|
|
|
|
|
@param Buffer Pointer to the buffer to carry out the sum operation.
|
|
|
|
@param Length The size, in bytes, of Buffer.
|
|
|
|
|
|
|
|
@return Sum The sum of Buffer with carry bits dropped during additions.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINT16
|
|
|
|
EFIAPI
|
|
|
|
CalculateSum16 (
|
|
|
|
IN CONST UINT16 *Buffer,
|
|
|
|
IN UINTN Length
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINT16 Sum;
|
|
|
|
UINTN Count;
|
|
|
|
|
|
|
|
ASSERT (Buffer != NULL);
|
|
|
|
ASSERT (((UINTN) Buffer & 0x1) == 0);
|
|
|
|
ASSERT ((Length & 0x1) == 0);
|
|
|
|
ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));
|
|
|
|
|
|
|
|
|
|
|
|
for (Sum = 0, Count = 0; Count < Length; Count++) {
|
|
|
|
Sum = (UINT16) (Sum + *(Buffer + Count));
|
|
|
|
}
|
|
|
|
|
|
|
|
return Sum;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Returns the two's complement checksum of all elements in a buffer of
|
|
|
|
16-bit values.
|
|
|
|
|
|
|
|
This function first calculates the sum of the 16-bit values in the buffer
|
|
|
|
specified by Buffer and Length. The carry bits in the result of addition
|
|
|
|
are dropped. Then, the two's complement of the sum is returned. If Length
|
|
|
|
is 0, then 0 is returned.
|
|
|
|
|
|
|
|
If Buffer is NULL, then ASSERT().
|
|
|
|
If Buffer is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
If Length is not aligned on a 16-bit boundary, then ASSERT().
|
|
|
|
If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
|
|
|
|
|
|
|
|
@param Buffer Pointer to the buffer to carry out the checksum operation.
|
|
|
|
@param Length The size, in bytes, of Buffer.
|
|
|
|
|
|
|
|
@return Checksum The 2's complement checksum of Buffer.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINT16
|
|
|
|
EFIAPI
|
|
|
|
CalculateCheckSum16 (
|
|
|
|
IN CONST UINT16 *Buffer,
|
|
|
|
IN UINTN Length
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINT16 CheckSum;
|
|
|
|
|
|
|
|
CheckSum = CalculateSum16 (Buffer, Length);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Return the checksum based on 2's complement.
|
|
|
|
//
|
|
|
|
return (UINT16) (0x10000 - CheckSum);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Returns the sum of all elements in a buffer of 32-bit values. During
|
|
|
|
calculation, the carry bits are dropped.
|
|
|
|
|
|
|
|
This function calculates the sum of the 32-bit values in the buffer
|
|
|
|
specified by Buffer and Length. The carry bits in result of addition are dropped.
|
|
|
|
The 32-bit result is returned. If Length is 0, then 0 is returned.
|
|
|
|
|
|
|
|
If Buffer is NULL, then ASSERT().
|
|
|
|
If Buffer is not aligned on a 32-bit boundary, then ASSERT().
|
|
|
|
If Length is not aligned on a 32-bit boundary, then ASSERT().
|
|
|
|
If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
|
|
|
|
|
|
|
|
@param Buffer Pointer to the buffer to carry out the sum operation.
|
|
|
|
@param Length The size, in bytes, of Buffer.
|
|
|
|
|
|
|
|
@return Sum The sum of Buffer with carry bits dropped during additions.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINT32
|
|
|
|
EFIAPI
|
|
|
|
CalculateSum32 (
|
|
|
|
IN CONST UINT32 *Buffer,
|
|
|
|
IN UINTN Length
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINT32 Sum;
|
|
|
|
UINTN Count;
|
|
|
|
|
|
|
|
ASSERT (Buffer != NULL);
|
|
|
|
ASSERT (((UINTN) Buffer & 0x3) == 0);
|
|
|
|
ASSERT ((Length & 0x3) == 0);
|
|
|
|
ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));
|
|
|
|
|
|
|
|
|
|
|
|
for (Sum = 0, Count = 0; Count < Length; Count++) {
|
|
|
|
Sum = Sum + *(Buffer + Count);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Sum;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Returns the two's complement checksum of all elements in a buffer of
|
|
|
|
32-bit values.
|
|
|
|
|
|
|
|
This function first calculates the sum of the 32-bit values in the buffer
|
|
|
|
specified by Buffer and Length. The carry bits in the result of addition
|
|
|
|
are dropped. Then, the two's complement of the sum is returned. If Length
|
|
|
|
is 0, then 0 is returned.
|
|
|
|
|
|
|
|
If Buffer is NULL, then ASSERT().
|
|
|
|
If Buffer is not aligned on a 32-bit boundary, then ASSERT().
|
|
|
|
If Length is not aligned on a 32-bit boundary, then ASSERT().
|
|
|
|
If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
|
|
|
|
|
|
|
|
@param Buffer Pointer to the buffer to carry out the checksum operation.
|
|
|
|
@param Length The size, in bytes, of Buffer.
|
|
|
|
|
|
|
|
@return Checksum The 2's complement checksum of Buffer.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINT32
|
|
|
|
EFIAPI
|
|
|
|
CalculateCheckSum32 (
|
|
|
|
IN CONST UINT32 *Buffer,
|
|
|
|
IN UINTN Length
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINT32 CheckSum;
|
|
|
|
|
|
|
|
CheckSum = CalculateSum32 (Buffer, Length);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Return the checksum based on 2's complement.
|
|
|
|
//
|
|
|
|
return (UINT32) ((UINT32)(-1) - CheckSum + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Returns the sum of all elements in a buffer of 64-bit values. During
|
|
|
|
calculation, the carry bits are dropped.
|
|
|
|
|
|
|
|
This function calculates the sum of the 64-bit values in the buffer
|
|
|
|
specified by Buffer and Length. The carry bits in result of addition are dropped.
|
|
|
|
The 64-bit result is returned. If Length is 0, then 0 is returned.
|
|
|
|
|
|
|
|
If Buffer is NULL, then ASSERT().
|
|
|
|
If Buffer is not aligned on a 64-bit boundary, then ASSERT().
|
|
|
|
If Length is not aligned on a 64-bit boundary, then ASSERT().
|
|
|
|
If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
|
|
|
|
|
|
|
|
@param Buffer Pointer to the buffer to carry out the sum operation.
|
|
|
|
@param Length The size, in bytes, of Buffer.
|
|
|
|
|
|
|
|
@return Sum The sum of Buffer with carry bits dropped during additions.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINT64
|
|
|
|
EFIAPI
|
|
|
|
CalculateSum64 (
|
|
|
|
IN CONST UINT64 *Buffer,
|
|
|
|
IN UINTN Length
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINT64 Sum;
|
|
|
|
UINTN Count;
|
|
|
|
|
|
|
|
ASSERT (Buffer != NULL);
|
|
|
|
ASSERT (((UINTN) Buffer & 0x7) == 0);
|
|
|
|
ASSERT ((Length & 0x7) == 0);
|
|
|
|
ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));
|
|
|
|
|
|
|
|
for (Sum = 0, Count = 0; Count < Length; Count++) {
|
|
|
|
Sum = Sum + *(Buffer + Count);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Sum;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Returns the two's complement checksum of all elements in a buffer of
|
|
|
|
64-bit values.
|
|
|
|
|
|
|
|
This function first calculates the sum of the 64-bit values in the buffer
|
|
|
|
specified by Buffer and Length. The carry bits in the result of addition
|
|
|
|
are dropped. Then, the two's complement of the sum is returned. If Length
|
|
|
|
is 0, then 0 is returned.
|
|
|
|
|
|
|
|
If Buffer is NULL, then ASSERT().
|
|
|
|
If Buffer is not aligned on a 64-bit boundary, then ASSERT().
|
|
|
|
If Length is not aligned on a 64-bit boundary, then ASSERT().
|
|
|
|
If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
|
|
|
|
|
|
|
|
@param Buffer Pointer to the buffer to carry out the checksum operation.
|
|
|
|
@param Length The size, in bytes, of Buffer.
|
|
|
|
|
|
|
|
@return Checksum The 2's complement checksum of Buffer.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINT64
|
|
|
|
EFIAPI
|
|
|
|
CalculateCheckSum64 (
|
|
|
|
IN CONST UINT64 *Buffer,
|
|
|
|
IN UINTN Length
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINT64 CheckSum;
|
|
|
|
|
|
|
|
CheckSum = CalculateSum64 (Buffer, Length);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Return the checksum based on 2's complement.
|
|
|
|
//
|
|
|
|
return (UINT64) ((UINT64)(-1) - CheckSum + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|