• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2   Utility functions to generate checksum based on 2's complement
3   algorithm.
4 
5   Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
6   This program and the accompanying materials
7   are licensed and made available under the terms and conditions of the BSD License
8   which accompanies this distribution.  The full text of the license may be found at
9   http://opensource.org/licenses/bsd-license.php.
10 
11   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 
14 **/
15 
16 #include "BaseLibInternals.h"
17 
18 /**
19   Returns the sum of all elements in a buffer in unit of UINT8.
20   During calculation, the carry bits are dropped.
21 
22   This function calculates the sum of all elements in a buffer
23   in unit of UINT8. The carry bits in result of addition are dropped.
24   The result is returned as UINT8. If Length is Zero, then Zero is
25   returned.
26 
27   If Buffer is NULL, then ASSERT().
28   If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
29 
30   @param  Buffer      The pointer to the buffer to carry out the sum operation.
31   @param  Length      The size, in bytes, of Buffer.
32 
33   @return Sum         The sum of Buffer with carry bits dropped during additions.
34 
35 **/
36 UINT8
37 EFIAPI
CalculateSum8(IN CONST UINT8 * Buffer,IN UINTN Length)38 CalculateSum8 (
39   IN      CONST UINT8              *Buffer,
40   IN      UINTN                     Length
41   )
42 {
43   UINT8     Sum;
44   UINTN     Count;
45 
46   ASSERT (Buffer != NULL);
47   ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));
48 
49   for (Sum = 0, Count = 0; Count < Length; Count++) {
50     Sum = (UINT8) (Sum + *(Buffer + Count));
51   }
52 
53   return Sum;
54 }
55 
56 
57 /**
58   Returns the two's complement checksum of all elements in a buffer
59   of 8-bit values.
60 
61   This function first calculates the sum of the 8-bit values in the
62   buffer specified by Buffer and Length.  The carry bits in the result
63   of addition are dropped. Then, the two's complement of the sum is
64   returned.  If Length is 0, then 0 is returned.
65 
66   If Buffer is NULL, then ASSERT().
67   If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
68 
69   @param  Buffer      The pointer to the buffer to carry out the checksum operation.
70   @param  Length      The size, in bytes, of Buffer.
71 
72   @return Checksum    The 2's complement checksum of Buffer.
73 
74 **/
75 UINT8
76 EFIAPI
CalculateCheckSum8(IN CONST UINT8 * Buffer,IN UINTN Length)77 CalculateCheckSum8 (
78   IN      CONST UINT8              *Buffer,
79   IN      UINTN                     Length
80   )
81 {
82   UINT8     CheckSum;
83 
84   CheckSum = CalculateSum8 (Buffer, Length);
85 
86   //
87   // Return the checksum based on 2's complement.
88   //
89   return (UINT8) (0x100 - CheckSum);
90 }
91 
92 /**
93   Returns the sum of all elements in a buffer of 16-bit values.  During
94   calculation, the carry bits are dropped.
95 
96   This function calculates the sum of the 16-bit values in the buffer
97   specified by Buffer and Length. The carry bits in result of addition are dropped.
98   The 16-bit result is returned.  If Length is 0, then 0 is returned.
99 
100   If Buffer is NULL, then ASSERT().
101   If Buffer is not aligned on a 16-bit boundary, then ASSERT().
102   If Length is not aligned on a 16-bit boundary, then ASSERT().
103   If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
104 
105   @param  Buffer      The pointer to the buffer to carry out the sum operation.
106   @param  Length      The size, in bytes, of Buffer.
107 
108   @return Sum         The sum of Buffer with carry bits dropped during additions.
109 
110 **/
111 UINT16
112 EFIAPI
CalculateSum16(IN CONST UINT16 * Buffer,IN UINTN Length)113 CalculateSum16 (
114   IN      CONST UINT16             *Buffer,
115   IN      UINTN                     Length
116   )
117 {
118   UINT16    Sum;
119   UINTN     Count;
120   UINTN     Total;
121 
122   ASSERT (Buffer != NULL);
123   ASSERT (((UINTN) Buffer & 0x1) == 0);
124   ASSERT ((Length & 0x1) == 0);
125   ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));
126 
127   Total = Length / sizeof (*Buffer);
128   for (Sum = 0, Count = 0; Count < Total; Count++) {
129     Sum = (UINT16) (Sum + *(Buffer + Count));
130   }
131 
132   return Sum;
133 }
134 
135 
136 /**
137   Returns the two's complement checksum of all elements in a buffer of
138   16-bit values.
139 
140   This function first calculates the sum of the 16-bit values in the buffer
141   specified by Buffer and Length.  The carry bits in the result of addition
142   are dropped. Then, the two's complement of the sum is returned.  If Length
143   is 0, then 0 is returned.
144 
145   If Buffer is NULL, then ASSERT().
146   If Buffer is not aligned on a 16-bit boundary, then ASSERT().
147   If Length is not aligned on a 16-bit boundary, then ASSERT().
148   If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
149 
150   @param  Buffer      The pointer to the buffer to carry out the checksum operation.
151   @param  Length      The size, in bytes, of Buffer.
152 
153   @return Checksum    The 2's complement checksum of Buffer.
154 
155 **/
156 UINT16
157 EFIAPI
CalculateCheckSum16(IN CONST UINT16 * Buffer,IN UINTN Length)158 CalculateCheckSum16 (
159   IN      CONST UINT16             *Buffer,
160   IN      UINTN                     Length
161   )
162 {
163   UINT16     CheckSum;
164 
165   CheckSum = CalculateSum16 (Buffer, Length);
166 
167   //
168   // Return the checksum based on 2's complement.
169   //
170   return (UINT16) (0x10000 - CheckSum);
171 }
172 
173 
174 /**
175   Returns the sum of all elements in a buffer of 32-bit values. During
176   calculation, the carry bits are dropped.
177 
178   This function calculates the sum of the 32-bit values in the buffer
179   specified by Buffer and Length. The carry bits in result of addition are dropped.
180   The 32-bit result is returned. If Length is 0, then 0 is returned.
181 
182   If Buffer is NULL, then ASSERT().
183   If Buffer is not aligned on a 32-bit boundary, then ASSERT().
184   If Length is not aligned on a 32-bit boundary, then ASSERT().
185   If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
186 
187   @param  Buffer      The pointer to the buffer to carry out the sum operation.
188   @param  Length      The size, in bytes, of Buffer.
189 
190   @return Sum         The sum of Buffer with carry bits dropped during additions.
191 
192 **/
193 UINT32
194 EFIAPI
CalculateSum32(IN CONST UINT32 * Buffer,IN UINTN Length)195 CalculateSum32 (
196   IN      CONST UINT32             *Buffer,
197   IN      UINTN                     Length
198   )
199 {
200   UINT32    Sum;
201   UINTN     Count;
202   UINTN     Total;
203 
204   ASSERT (Buffer != NULL);
205   ASSERT (((UINTN) Buffer & 0x3) == 0);
206   ASSERT ((Length & 0x3) == 0);
207   ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));
208 
209   Total = Length / sizeof (*Buffer);
210   for (Sum = 0, Count = 0; Count < Total; Count++) {
211     Sum = Sum + *(Buffer + Count);
212   }
213 
214   return Sum;
215 }
216 
217 
218 /**
219   Returns the two's complement checksum of all elements in a buffer of
220   32-bit values.
221 
222   This function first calculates the sum of the 32-bit values in the buffer
223   specified by Buffer and Length.  The carry bits in the result of addition
224   are dropped. Then, the two's complement of the sum is returned.  If Length
225   is 0, then 0 is returned.
226 
227   If Buffer is NULL, then ASSERT().
228   If Buffer is not aligned on a 32-bit boundary, then ASSERT().
229   If Length is not aligned on a 32-bit boundary, then ASSERT().
230   If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
231 
232   @param  Buffer      The pointer to the buffer to carry out the checksum operation.
233   @param  Length      The size, in bytes, of Buffer.
234 
235   @return Checksum    The 2's complement checksum of Buffer.
236 
237 **/
238 UINT32
239 EFIAPI
CalculateCheckSum32(IN CONST UINT32 * Buffer,IN UINTN Length)240 CalculateCheckSum32 (
241   IN      CONST UINT32             *Buffer,
242   IN      UINTN                     Length
243   )
244 {
245   UINT32     CheckSum;
246 
247   CheckSum = CalculateSum32 (Buffer, Length);
248 
249   //
250   // Return the checksum based on 2's complement.
251   //
252   return (UINT32) ((UINT32)(-1) - CheckSum + 1);
253 }
254 
255 
256 /**
257   Returns the sum of all elements in a buffer of 64-bit values.  During
258   calculation, the carry bits are dropped.
259 
260   This function calculates the sum of the 64-bit values in the buffer
261   specified by Buffer and Length. The carry bits in result of addition are dropped.
262   The 64-bit result is returned.  If Length is 0, then 0 is returned.
263 
264   If Buffer is NULL, then ASSERT().
265   If Buffer is not aligned on a 64-bit boundary, then ASSERT().
266   If Length is not aligned on a 64-bit boundary, then ASSERT().
267   If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
268 
269   @param  Buffer      The pointer to the buffer to carry out the sum operation.
270   @param  Length      The size, in bytes, of Buffer.
271 
272   @return Sum         The sum of Buffer with carry bits dropped during additions.
273 
274 **/
275 UINT64
276 EFIAPI
CalculateSum64(IN CONST UINT64 * Buffer,IN UINTN Length)277 CalculateSum64 (
278   IN      CONST UINT64             *Buffer,
279   IN      UINTN                     Length
280   )
281 {
282   UINT64    Sum;
283   UINTN     Count;
284   UINTN     Total;
285 
286   ASSERT (Buffer != NULL);
287   ASSERT (((UINTN) Buffer & 0x7) == 0);
288   ASSERT ((Length & 0x7) == 0);
289   ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));
290 
291   Total = Length / sizeof (*Buffer);
292   for (Sum = 0, Count = 0; Count < Total; Count++) {
293     Sum = Sum + *(Buffer + Count);
294   }
295 
296   return Sum;
297 }
298 
299 
300 /**
301   Returns the two's complement checksum of all elements in a buffer of
302   64-bit values.
303 
304   This function first calculates the sum of the 64-bit values in the buffer
305   specified by Buffer and Length.  The carry bits in the result of addition
306   are dropped. Then, the two's complement of the sum is returned.  If Length
307   is 0, then 0 is returned.
308 
309   If Buffer is NULL, then ASSERT().
310   If Buffer is not aligned on a 64-bit boundary, then ASSERT().
311   If Length is not aligned on a 64-bit boundary, then ASSERT().
312   If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
313 
314   @param  Buffer      The pointer to the buffer to carry out the checksum operation.
315   @param  Length      The size, in bytes, of Buffer.
316 
317   @return Checksum    The 2's complement checksum of Buffer.
318 
319 **/
320 UINT64
321 EFIAPI
CalculateCheckSum64(IN CONST UINT64 * Buffer,IN UINTN Length)322 CalculateCheckSum64 (
323   IN      CONST UINT64             *Buffer,
324   IN      UINTN                     Length
325   )
326 {
327   UINT64     CheckSum;
328 
329   CheckSum = CalculateSum64 (Buffer, Length);
330 
331   //
332   // Return the checksum based on 2's complement.
333   //
334   return (UINT64) ((UINT64)(-1) - CheckSum + 1);
335 }
336 
337 
338