]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseSafeIntLib/SafeIntLib32.c
MdePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdePkg / Library / BaseSafeIntLib / SafeIntLib32.c
1 /** @file
2 This library provides helper functions to prevent integer overflow during
3 type conversion, addition, subtraction, and multiplication.
4
5 Copyright (c) 2017, Microsoft Corporation
6
7 All rights reserved.
8 SPDX-License-Identifier: BSD-2-Clause-Patent
9
10 **/
11
12 #include <Base.h>
13 #include <Library/SafeIntLib.h>
14 #include <Library/BaseLib.h>
15
16 /**
17 INT32 -> UINTN conversion
18
19 Converts the value specified by Operand to a value specified by Result type
20 and stores the converted value into the caller allocated output buffer
21 specified by Result. The caller must pass in a Result buffer that is at
22 least as large as the Result type.
23
24 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
25
26 If the conversion results in an overflow or an underflow condition, then
27 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
28
29 @param[in] Operand Operand to be converted to new type
30 @param[out] Result Pointer to the result of conversion
31
32 @retval RETURN_SUCCESS Successful conversion
33 @retval RETURN_BUFFER_TOO_SMALL Overflow
34 @retval RETURN_INVALID_PARAMETER Result is NULL
35 **/
36 RETURN_STATUS
37 EFIAPI
38 SafeInt32ToUintn (
39 IN INT32 Operand,
40 OUT UINTN *Result
41 )
42 {
43 return SafeInt32ToUint32 (Operand, (UINT32 *)Result);
44 }
45
46 /**
47 UINT32 -> INTN conversion
48
49 Converts the value specified by Operand to a value specified by Result type
50 and stores the converted value into the caller allocated output buffer
51 specified by Result. The caller must pass in a Result buffer that is at
52 least as large as the Result type.
53
54 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
55
56 If the conversion results in an overflow or an underflow condition, then
57 Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
58
59 @param[in] Operand Operand to be converted to new type
60 @param[out] Result Pointer to the result of conversion
61
62 @retval RETURN_SUCCESS Successful conversion
63 @retval RETURN_BUFFER_TOO_SMALL Overflow
64 @retval RETURN_INVALID_PARAMETER Result is NULL
65 **/
66 RETURN_STATUS
67 EFIAPI
68 SafeUint32ToIntn (
69 IN UINT32 Operand,
70 OUT INTN *Result
71 )
72 {
73 return SafeUint32ToInt32 (Operand, (INT32 *)Result);
74 }
75
76 /**
77 INTN -> INT32 conversion
78
79 Converts the value specified by Operand to a value specified by Result type
80 and stores the converted value into the caller allocated output buffer
81 specified by Result. The caller must pass in a Result buffer that is at
82 least as large as the Result type.
83
84 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
85
86 If the conversion results in an overflow or an underflow condition, then
87 Result is set to INT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
88
89 @param[in] Operand Operand to be converted to new type
90 @param[out] Result Pointer to the result of conversion
91
92 @retval RETURN_SUCCESS Successful conversion
93 @retval RETURN_BUFFER_TOO_SMALL Overflow
94 @retval RETURN_INVALID_PARAMETER Result is NULL
95 **/
96 RETURN_STATUS
97 EFIAPI
98 SafeIntnToInt32 (
99 IN INTN Operand,
100 OUT INT32 *Result
101 )
102 {
103 if (Result == NULL) {
104 return RETURN_INVALID_PARAMETER;
105 }
106
107 *Result = (INT32)Operand;
108 return RETURN_SUCCESS;
109 }
110
111 /**
112 INTN -> UINT32 conversion
113
114 Converts the value specified by Operand to a value specified by Result type
115 and stores the converted value into the caller allocated output buffer
116 specified by Result. The caller must pass in a Result buffer that is at
117 least as large as the Result type.
118
119 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
120
121 If the conversion results in an overflow or an underflow condition, then
122 Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
123
124 @param[in] Operand Operand to be converted to new type
125 @param[out] Result Pointer to the result of conversion
126
127 @retval RETURN_SUCCESS Successful conversion
128 @retval RETURN_BUFFER_TOO_SMALL Overflow
129 @retval RETURN_INVALID_PARAMETER Result is NULL
130 **/
131 RETURN_STATUS
132 EFIAPI
133 SafeIntnToUint32 (
134 IN INTN Operand,
135 OUT UINT32 *Result
136 )
137 {
138 RETURN_STATUS Status;
139
140 if (Result == NULL) {
141 return RETURN_INVALID_PARAMETER;
142 }
143
144 if (Operand >= 0) {
145 *Result = (UINT32)Operand;
146 Status = RETURN_SUCCESS;
147 } else {
148 *Result = UINT32_ERROR;
149 Status = RETURN_BUFFER_TOO_SMALL;
150 }
151
152 return Status;
153 }
154
155 /**
156 UINTN -> UINT32 conversion
157
158 Converts the value specified by Operand to a value specified by Result type
159 and stores the converted value into the caller allocated output buffer
160 specified by Result. The caller must pass in a Result buffer that is at
161 least as large as the Result type.
162
163 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
164
165 If the conversion results in an overflow or an underflow condition, then
166 Result is set to UINT32_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
167
168 @param[in] Operand Operand to be converted to new type
169 @param[out] Result Pointer to the result of conversion
170
171 @retval RETURN_SUCCESS Successful conversion
172 @retval RETURN_BUFFER_TOO_SMALL Overflow
173 @retval RETURN_INVALID_PARAMETER Result is NULL
174 **/
175 RETURN_STATUS
176 EFIAPI
177 SafeUintnToUint32 (
178 IN UINTN Operand,
179 OUT UINT32 *Result
180 )
181 {
182 if (Result == NULL) {
183 return RETURN_INVALID_PARAMETER;
184 }
185
186 *Result = (UINT32)Operand;
187 return RETURN_SUCCESS;
188 }
189
190 /**
191 UINTN -> INT64 conversion
192
193 Converts the value specified by Operand to a value specified by Result type
194 and stores the converted value into the caller allocated output buffer
195 specified by Result. The caller must pass in a Result buffer that is at
196 least as large as the Result type.
197
198 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
199
200 If the conversion results in an overflow or an underflow condition, then
201 Result is set to INT64_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
202
203 @param[in] Operand Operand to be converted to new type
204 @param[out] Result Pointer to the result of conversion
205
206 @retval RETURN_SUCCESS Successful conversion
207 @retval RETURN_BUFFER_TOO_SMALL Overflow
208 @retval RETURN_INVALID_PARAMETER Result is NULL
209 **/
210 RETURN_STATUS
211 EFIAPI
212 SafeUintnToInt64 (
213 IN UINTN Operand,
214 OUT INT64 *Result
215 )
216 {
217 if (Result == NULL) {
218 return RETURN_INVALID_PARAMETER;
219 }
220
221 *Result = (INT64)Operand;
222 return RETURN_SUCCESS;
223 }
224
225 /**
226 INT64 -> INTN conversion
227
228 Converts the value specified by Operand to a value specified by Result type
229 and stores the converted value into the caller allocated output buffer
230 specified by Result. The caller must pass in a Result buffer that is at
231 least as large as the Result type.
232
233 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
234
235 If the conversion results in an overflow or an underflow condition, then
236 Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
237
238 @param[in] Operand Operand to be converted to new type
239 @param[out] Result Pointer to the result of conversion
240
241 @retval RETURN_SUCCESS Successful conversion
242 @retval RETURN_BUFFER_TOO_SMALL Overflow
243 @retval RETURN_INVALID_PARAMETER Result is NULL
244 **/
245 RETURN_STATUS
246 EFIAPI
247 SafeInt64ToIntn (
248 IN INT64 Operand,
249 OUT INTN *Result
250 )
251 {
252 return SafeInt64ToInt32 (Operand, (INT32 *)Result);
253 }
254
255 /**
256 INT64 -> UINTN conversion
257
258 Converts the value specified by Operand to a value specified by Result type
259 and stores the converted value into the caller allocated output buffer
260 specified by Result. The caller must pass in a Result buffer that is at
261 least as large as the Result type.
262
263 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
264
265 If the conversion results in an overflow or an underflow condition, then
266 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
267
268 @param[in] Operand Operand to be converted to new type
269 @param[out] Result Pointer to the result of conversion
270
271 @retval RETURN_SUCCESS Successful conversion
272 @retval RETURN_BUFFER_TOO_SMALL Overflow
273 @retval RETURN_INVALID_PARAMETER Result is NULL
274 **/
275 RETURN_STATUS
276 EFIAPI
277 SafeInt64ToUintn (
278 IN INT64 Operand,
279 OUT UINTN *Result
280 )
281 {
282 return SafeInt64ToUint32 (Operand, (UINT32 *)Result);
283 }
284
285 /**
286 UINT64 -> UINTN conversion
287
288 Converts the value specified by Operand to a value specified by Result type
289 and stores the converted value into the caller allocated output buffer
290 specified by Result. The caller must pass in a Result buffer that is at
291 least as large as the Result type.
292
293 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
294
295 If the conversion results in an overflow or an underflow condition, then
296 Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
297
298 @param[in] Operand Operand to be converted to new type
299 @param[out] Result Pointer to the result of conversion
300
301 @retval RETURN_SUCCESS Successful conversion
302 @retval RETURN_BUFFER_TOO_SMALL Overflow
303 @retval RETURN_INVALID_PARAMETER Result is NULL
304 **/
305 RETURN_STATUS
306 EFIAPI
307 SafeUint64ToUintn (
308 IN UINT64 Operand,
309 OUT UINTN *Result
310 )
311 {
312 return SafeUint64ToUint32 ((UINT64) Operand, (UINT32 *)Result);
313 }
314
315 /**
316 UINTN addition
317
318 Performs the requested operation using the input parameters into a value
319 specified by Result type and stores the converted value into the caller
320 allocated output buffer specified by Result. The caller must pass in a
321 Result buffer that is at least as large as the Result type.
322
323 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
324
325 If the requested operation results in an overflow or an underflow condition,
326 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
327
328 @param[in] Augend A number to which addend will be added
329 @param[in] Addend A number to be added to another
330 @param[out] Result Pointer to the result of addition
331
332 @retval RETURN_SUCCESS Successful addition
333 @retval RETURN_BUFFER_TOO_SMALL Overflow
334 @retval RETURN_INVALID_PARAMETER Result is NULL
335 **/
336 RETURN_STATUS
337 EFIAPI
338 SafeUintnAdd (
339 IN UINTN Augend,
340 IN UINTN Addend,
341 OUT UINTN *Result
342 )
343 {
344 RETURN_STATUS Status;
345
346 if (Result == NULL) {
347 return RETURN_INVALID_PARAMETER;
348 }
349
350 if ((Augend + Addend) >= Augend) {
351 *Result = (Augend + Addend);
352 Status = RETURN_SUCCESS;
353 } else {
354 *Result = UINTN_ERROR;
355 Status = RETURN_BUFFER_TOO_SMALL;
356 }
357
358 return Status;
359 }
360
361 /**
362 UINTN subtraction
363
364 Performs the requested operation using the input parameters into a value
365 specified by Result type and stores the converted value into the caller
366 allocated output buffer specified by Result. The caller must pass in a
367 Result buffer that is at least as large as the Result type.
368
369 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
370
371 If the requested operation results in an overflow or an underflow condition,
372 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
373
374 @param[in] Minuend A number from which another is to be subtracted.
375 @param[in] Subtrahend A number to be subtracted from another
376 @param[out] Result Pointer to the result of subtraction
377
378 @retval RETURN_SUCCESS Successful subtraction
379 @retval RETURN_BUFFER_TOO_SMALL Underflow
380 @retval RETURN_INVALID_PARAMETER Result is NULL
381 **/
382 RETURN_STATUS
383 EFIAPI
384 SafeUintnSub (
385 IN UINTN Minuend,
386 IN UINTN Subtrahend,
387 OUT UINTN *Result
388 )
389 {
390 RETURN_STATUS Status;
391
392 if (Result == NULL) {
393 return RETURN_INVALID_PARAMETER;
394 }
395
396 if (Minuend >= Subtrahend) {
397 *Result = (Minuend - Subtrahend);
398 Status = RETURN_SUCCESS;
399 } else {
400 *Result = UINTN_ERROR;
401 Status = RETURN_BUFFER_TOO_SMALL;
402 }
403
404 return Status;
405 }
406
407 /**
408 UINTN multiplication
409
410 Performs the requested operation using the input parameters into a value
411 specified by Result type and stores the converted value into the caller
412 allocated output buffer specified by Result. The caller must pass in a
413 Result buffer that is at least as large as the Result type.
414
415 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
416
417 If the requested operation results in an overflow or an underflow condition,
418 then Result is set to UINTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
419
420 @param[in] Multiplicand A number that is to be multiplied by another
421 @param[in] Multiplier A number by which the multiplicand is to be multiplied
422 @param[out] Result Pointer to the result of multiplication
423
424 @retval RETURN_SUCCESS Successful multiplication
425 @retval RETURN_BUFFER_TOO_SMALL Overflow
426 @retval RETURN_INVALID_PARAMETER Result is NULL
427 **/
428 RETURN_STATUS
429 EFIAPI
430 SafeUintnMult (
431 IN UINTN Multiplicand,
432 IN UINTN Multiplier,
433 OUT UINTN *Result
434 )
435 {
436 UINT64 IntermediateResult;
437
438 IntermediateResult = ((UINT64) Multiplicand) *((UINT64) Multiplier);
439
440 return SafeUint64ToUintn (IntermediateResult, Result);
441 }
442
443 /**
444 INTN Addition
445
446 Performs the requested operation using the input parameters into a value
447 specified by Result type and stores the converted value into the caller
448 allocated output buffer specified by Result. The caller must pass in a
449 Result buffer that is at least as large as the Result type.
450
451 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
452
453 If the requested operation results in an overflow or an underflow condition,
454 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
455
456 @param[in] Augend A number to which addend will be added
457 @param[in] Addend A number to be added to another
458 @param[out] Result Pointer to the result of addition
459
460 @retval RETURN_SUCCESS Successful addition
461 @retval RETURN_BUFFER_TOO_SMALL Overflow
462 @retval RETURN_INVALID_PARAMETER Result is NULL
463 **/
464 RETURN_STATUS
465 EFIAPI
466 SafeIntnAdd (
467 IN INTN Augend,
468 IN INTN Addend,
469 OUT INTN *Result
470 )
471 {
472 return SafeInt64ToIntn (((INT64)Augend) + ((INT64)Addend), Result);
473 }
474
475 /**
476 INTN Subtraction
477
478 Performs the requested operation using the input parameters into a value
479 specified by Result type and stores the converted value into the caller
480 allocated output buffer specified by Result. The caller must pass in a
481 Result buffer that is at least as large as the Result type.
482
483 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
484
485 If the requested operation results in an overflow or an underflow condition,
486 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
487
488 @param[in] Minuend A number from which another is to be subtracted.
489 @param[in] Subtrahend A number to be subtracted from another
490 @param[out] Result Pointer to the result of subtraction
491
492 @retval RETURN_SUCCESS Successful subtraction
493 @retval RETURN_BUFFER_TOO_SMALL Underflow
494 @retval RETURN_INVALID_PARAMETER Result is NULL
495 **/
496 RETURN_STATUS
497 EFIAPI
498 SafeIntnSub (
499 IN INTN Minuend,
500 IN INTN Subtrahend,
501 OUT INTN *Result
502 )
503 {
504 return SafeInt64ToIntn (((INT64)Minuend) - ((INT64)Subtrahend), Result);
505 }
506
507 /**
508 INTN multiplication
509
510 Performs the requested operation using the input parameters into a value
511 specified by Result type and stores the converted value into the caller
512 allocated output buffer specified by Result. The caller must pass in a
513 Result buffer that is at least as large as the Result type.
514
515 If Result is NULL, RETURN_INVALID_PARAMETER is returned.
516
517 If the requested operation results in an overflow or an underflow condition,
518 then Result is set to INTN_ERROR and RETURN_BUFFER_TOO_SMALL is returned.
519
520 @param[in] Multiplicand A number that is to be multiplied by another
521 @param[in] Multiplier A number by which the multiplicand is to be multiplied
522 @param[out] Result Pointer to the result of multiplication
523
524 @retval RETURN_SUCCESS Successful multiplication
525 @retval RETURN_BUFFER_TOO_SMALL Overflow
526 @retval RETURN_INVALID_PARAMETER Result is NULL
527 **/
528 RETURN_STATUS
529 EFIAPI
530 SafeIntnMult (
531 IN INTN Multiplicand,
532 IN INTN Multiplier,
533 OUT INTN *Result
534 )
535 {
536 return SafeInt64ToIntn (MultS64x64 (Multiplicand, Multiplier), Result);
537 }
538