| 
									
										
										
										
											2021-10-28 07:20:03 +08:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2022-05-03 18:52:38 +08:00
										 |  |  |  * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2021-10-28 07:20:03 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License 2.0 (the "License").  You may not use | 
					
						
							|  |  |  |  * this file except in compliance with the License.  You can obtain a copy | 
					
						
							|  |  |  |  * in the file LICENSE in the source distribution or at | 
					
						
							|  |  |  |  * https://www.openssl.org/source/license.html
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef OSSL_INTERNAL_SAFE_MATH_H
 | 
					
						
							|  |  |  | # define OSSL_INTERNAL_SAFE_MATH_H
 | 
					
						
							|  |  |  | # pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # include <openssl/e_os2.h>              /* For 'ossl_inline' */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # ifndef OPENSSL_NO_BUILTIN_OVERFLOW_CHECKING
 | 
					
						
							|  |  |  | #  ifdef __has_builtin
 | 
					
						
							|  |  |  | #   define has(func) __has_builtin(func)
 | 
					
						
							|  |  |  | #  elif __GNUC__ > 5
 | 
					
						
							|  |  |  | #   define has(func) 1
 | 
					
						
							|  |  |  | #  endif
 | 
					
						
							|  |  |  | # endif /* OPENSSL_NO_BUILTIN_OVERFLOW_CHECKING */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # ifndef has
 | 
					
						
							|  |  |  | #  define has(func) 0
 | 
					
						
							|  |  |  | # endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Safe addition helpers | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | # if has(__builtin_add_overflow)
 | 
					
						
							|  |  |  | #  define OSSL_SAFE_MATH_ADDS(type_name, type, min, max) \
 | 
					
						
							|  |  |  |     static ossl_inline ossl_unused type safe_add_ ## type_name(type a,       \ | 
					
						
							|  |  |  |                                                                type b,       \ | 
					
						
							|  |  |  |                                                                int *err)     \ | 
					
						
							|  |  |  |     {                                                                        \ | 
					
						
							|  |  |  |         type r;                                                              \ | 
					
						
							|  |  |  |                                                                              \ | 
					
						
							|  |  |  |         if (!__builtin_add_overflow(a, b, &r))                               \ | 
					
						
							|  |  |  |             return r;                                                        \ | 
					
						
							|  |  |  |         *err |= 1;                                                           \ | 
					
						
							|  |  |  |         return a < 0 ? min : max;                                            \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #  define OSSL_SAFE_MATH_ADDU(type_name, type, max) \
 | 
					
						
							|  |  |  |     static ossl_inline ossl_unused type safe_add_ ## type_name(type a,       \ | 
					
						
							|  |  |  |                                                                type b,       \ | 
					
						
							|  |  |  |                                                                int *err)     \ | 
					
						
							|  |  |  |     {                                                                        \ | 
					
						
							|  |  |  |         type r;                                                              \ | 
					
						
							|  |  |  |                                                                              \ | 
					
						
							|  |  |  |         if (!__builtin_add_overflow(a, b, &r))                               \ | 
					
						
							|  |  |  |             return r;                                                        \ | 
					
						
							|  |  |  |         *err |= 1;                                                           \ | 
					
						
							|  |  |  |         return a + b;                                                            \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # else  /* has(__builtin_add_overflow) */
 | 
					
						
							|  |  |  | #  define OSSL_SAFE_MATH_ADDS(type_name, type, min, max) \
 | 
					
						
							|  |  |  |     static ossl_inline ossl_unused type safe_add_ ## type_name(type a,       \ | 
					
						
							|  |  |  |                                                                type b,       \ | 
					
						
							|  |  |  |                                                                int *err)     \ | 
					
						
							|  |  |  |     {                                                                        \ | 
					
						
							|  |  |  |         if ((a < 0) ^ (b < 0)                                                \ | 
					
						
							|  |  |  |                 || (a > 0 && b <= max - a)                                   \ | 
					
						
							|  |  |  |                 || (a < 0 && b >= min - a)                                   \ | 
					
						
							|  |  |  |                 || a == 0)                                                   \ | 
					
						
							|  |  |  |             return a + b;                                                    \ | 
					
						
							|  |  |  |         *err |= 1;                                                           \ | 
					
						
							|  |  |  |         return a < 0 ? min : max;                                            \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #  define OSSL_SAFE_MATH_ADDU(type_name, type, max) \
 | 
					
						
							|  |  |  |     static ossl_inline ossl_unused type safe_add_ ## type_name(type a,       \ | 
					
						
							|  |  |  |                                                                type b,       \ | 
					
						
							|  |  |  |                                                                int *err)     \ | 
					
						
							|  |  |  |     {                                                                        \ | 
					
						
							|  |  |  |         if (b > max - a)                                                     \ | 
					
						
							|  |  |  |             *err |= 1;                                                       \ | 
					
						
							|  |  |  |         return a + b;                                                        \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | # endif /* has(__builtin_add_overflow) */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Safe subtraction helpers | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | # if has(__builtin_sub_overflow)
 | 
					
						
							|  |  |  | #  define OSSL_SAFE_MATH_SUBS(type_name, type, min, max) \
 | 
					
						
							|  |  |  |     static ossl_inline ossl_unused type safe_sub_ ## type_name(type a,       \ | 
					
						
							|  |  |  |                                                                type b,       \ | 
					
						
							|  |  |  |                                                                int *err)     \ | 
					
						
							|  |  |  |     {                                                                        \ | 
					
						
							|  |  |  |         type r;                                                              \ | 
					
						
							|  |  |  |                                                                              \ | 
					
						
							|  |  |  |         if (!__builtin_sub_overflow(a, b, &r))                               \ | 
					
						
							|  |  |  |             return r;                                                        \ | 
					
						
							|  |  |  |         *err |= 1;                                                           \ | 
					
						
							|  |  |  |         return a < 0 ? min : max;                                            \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # else  /* has(__builtin_sub_overflow) */
 | 
					
						
							|  |  |  | #  define OSSL_SAFE_MATH_SUBS(type_name, type, min, max) \
 | 
					
						
							|  |  |  |     static ossl_inline ossl_unused type safe_sub_ ## type_name(type a,       \ | 
					
						
							|  |  |  |                                                                type b,       \ | 
					
						
							|  |  |  |                                                                int *err)     \ | 
					
						
							|  |  |  |     {                                                                        \ | 
					
						
							|  |  |  |         if (!((a < 0) ^ (b < 0))                                             \ | 
					
						
							|  |  |  |                 || (b > 0 && a >= min + b)                                   \ | 
					
						
							|  |  |  |                 || (b < 0 && a <= max + b)                                   \ | 
					
						
							|  |  |  |                 || b == 0)                                                   \ | 
					
						
							|  |  |  |             return a - b;                                                    \ | 
					
						
							|  |  |  |         *err |= 1;                                                           \ | 
					
						
							|  |  |  |         return a < 0 ? min : max;                                            \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # endif /* has(__builtin_sub_overflow) */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # define OSSL_SAFE_MATH_SUBU(type_name, type) \
 | 
					
						
							|  |  |  |     static ossl_inline ossl_unused type safe_sub_ ## type_name(type a,       \ | 
					
						
							|  |  |  |                                                                type b,       \ | 
					
						
							|  |  |  |                                                                int *err)     \ | 
					
						
							|  |  |  |     {                                                                        \ | 
					
						
							|  |  |  |         if (b > a)                                                           \ | 
					
						
							|  |  |  |             *err |= 1;                                                       \ | 
					
						
							|  |  |  |         return a - b;                                                        \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Safe multiplication helpers | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | # if has(__builtin_mul_overflow)
 | 
					
						
							|  |  |  | #  define OSSL_SAFE_MATH_MULS(type_name, type, min, max) \
 | 
					
						
							|  |  |  |     static ossl_inline ossl_unused type safe_mul_ ## type_name(type a,       \ | 
					
						
							|  |  |  |                                                                type b,       \ | 
					
						
							|  |  |  |                                                                int *err)     \ | 
					
						
							|  |  |  |     {                                                                        \ | 
					
						
							|  |  |  |         type r;                                                              \ | 
					
						
							|  |  |  |                                                                              \ | 
					
						
							|  |  |  |         if (!__builtin_mul_overflow(a, b, &r))                               \ | 
					
						
							|  |  |  |             return r;                                                        \ | 
					
						
							|  |  |  |         *err |= 1;                                                           \ | 
					
						
							|  |  |  |         return (a < 0) ^ (b < 0) ? min : max;                                \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #  define OSSL_SAFE_MATH_MULU(type_name, type, max) \
 | 
					
						
							|  |  |  |     static ossl_inline ossl_unused type safe_mul_ ## type_name(type a,       \ | 
					
						
							|  |  |  |                                                                type b,       \ | 
					
						
							|  |  |  |                                                                int *err)     \ | 
					
						
							|  |  |  |     {                                                                        \ | 
					
						
							|  |  |  |         type r;                                                              \ | 
					
						
							|  |  |  |                                                                              \ | 
					
						
							|  |  |  |         if (!__builtin_mul_overflow(a, b, &r))                               \ | 
					
						
							|  |  |  |             return r;                                                        \ | 
					
						
							|  |  |  |         *err |= 1;                                                           \ | 
					
						
							|  |  |  |         return a * b;                                                          \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # else  /* has(__builtin_mul_overflow) */
 | 
					
						
							|  |  |  | #  define OSSL_SAFE_MATH_MULS(type_name, type, min, max) \
 | 
					
						
							|  |  |  |     static ossl_inline ossl_unused type safe_mul_ ## type_name(type a,       \ | 
					
						
							|  |  |  |                                                                type b,       \ | 
					
						
							|  |  |  |                                                                int *err)     \ | 
					
						
							|  |  |  |     {                                                                        \ | 
					
						
							|  |  |  |         if (a == 0 || b == 0)                                                \ | 
					
						
							|  |  |  |             return 0;                                                        \ | 
					
						
							|  |  |  |         if (a == 1)                                                          \ | 
					
						
							|  |  |  |             return b;                                                        \ | 
					
						
							|  |  |  |         if (b == 1)                                                          \ | 
					
						
							|  |  |  |             return a;                                                        \ | 
					
						
							|  |  |  |         if (a != min && b != min) {                                          \ | 
					
						
							|  |  |  |             const type x = a < 0 ? -a : a;                                   \ | 
					
						
							|  |  |  |             const type y = b < 0 ? -b : b;                                   \ | 
					
						
							|  |  |  |                                                                              \ | 
					
						
							|  |  |  |             if (x <= max / y)                                                \ | 
					
						
							|  |  |  |                 return a * b;                                                \ | 
					
						
							|  |  |  |         }                                                                    \ | 
					
						
							|  |  |  |         *err |= 1;                                                           \ | 
					
						
							|  |  |  |         return (a < 0) ^ (b < 0) ? min : max;                                \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #  define OSSL_SAFE_MATH_MULU(type_name, type, max) \
 | 
					
						
							|  |  |  |     static ossl_inline ossl_unused type safe_mul_ ## type_name(type a,       \ | 
					
						
							|  |  |  |                                                                type b,       \ | 
					
						
							|  |  |  |                                                                int *err)     \ | 
					
						
							|  |  |  |     {                                                                        \ | 
					
						
							| 
									
										
										
										
											2022-09-30 16:26:37 +08:00
										 |  |  |         if (b != 0 && a > max / b)                                           \ | 
					
						
							| 
									
										
										
										
											2021-10-28 07:20:03 +08:00
										 |  |  |             *err |= 1;                                                       \ | 
					
						
							|  |  |  |         return a * b;                                                        \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | # endif /* has(__builtin_mul_overflow) */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Safe division helpers | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | # define OSSL_SAFE_MATH_DIVS(type_name, type, min, max) \
 | 
					
						
							|  |  |  |     static ossl_inline ossl_unused type safe_div_ ## type_name(type a,       \ | 
					
						
							|  |  |  |                                                                type b,       \ | 
					
						
							|  |  |  |                                                                int *err)     \ | 
					
						
							|  |  |  |     {                                                                        \ | 
					
						
							|  |  |  |         if (b == 0) {                                                        \ | 
					
						
							|  |  |  |             *err |= 1;                                                       \ | 
					
						
							|  |  |  |             return a < 0 ? min : max;                                        \ | 
					
						
							|  |  |  |         }                                                                    \ | 
					
						
							|  |  |  |         if (b == -1 && a == min) {                                           \ | 
					
						
							|  |  |  |             *err |= 1;                                                       \ | 
					
						
							|  |  |  |             return max;                                                      \ | 
					
						
							|  |  |  |         }                                                                    \ | 
					
						
							|  |  |  |         return a / b;                                                        \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # define OSSL_SAFE_MATH_DIVU(type_name, type, max) \
 | 
					
						
							|  |  |  |     static ossl_inline ossl_unused type safe_div_ ## type_name(type a,       \ | 
					
						
							|  |  |  |                                                                type b,       \ | 
					
						
							|  |  |  |                                                                int *err)     \ | 
					
						
							|  |  |  |     {                                                                        \ | 
					
						
							|  |  |  |         if (b != 0)                                                          \ | 
					
						
							|  |  |  |             return a / b;                                                    \ | 
					
						
							|  |  |  |         *err |= 1;                                                           \ | 
					
						
							|  |  |  |         return max;                                                        \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Safe modulus helpers | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | # define OSSL_SAFE_MATH_MODS(type_name, type, min, max) \
 | 
					
						
							|  |  |  |     static ossl_inline ossl_unused type safe_mod_ ## type_name(type a,       \ | 
					
						
							|  |  |  |                                                                type b,       \ | 
					
						
							|  |  |  |                                                                int *err)     \ | 
					
						
							|  |  |  |     {                                                                        \ | 
					
						
							|  |  |  |         if (b == 0) {                                                        \ | 
					
						
							|  |  |  |             *err |= 1;                                                       \ | 
					
						
							|  |  |  |             return 0;                                                        \ | 
					
						
							|  |  |  |         }                                                                    \ | 
					
						
							|  |  |  |         if (b == -1 && a == min) {                                           \ | 
					
						
							|  |  |  |             *err |= 1;                                                       \ | 
					
						
							|  |  |  |             return max;                                                      \ | 
					
						
							|  |  |  |         }                                                                    \ | 
					
						
							|  |  |  |         return a % b;                                                        \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # define OSSL_SAFE_MATH_MODU(type_name, type) \
 | 
					
						
							|  |  |  |     static ossl_inline ossl_unused type safe_mod_ ## type_name(type a,       \ | 
					
						
							|  |  |  |                                                                type b,       \ | 
					
						
							|  |  |  |                                                                int *err)     \ | 
					
						
							|  |  |  |     {                                                                        \ | 
					
						
							|  |  |  |         if (b != 0)                                                          \ | 
					
						
							|  |  |  |             return a % b;                                                    \ | 
					
						
							|  |  |  |         *err |= 1;                                                           \ | 
					
						
							|  |  |  |         return 0;                                                            \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Safe negation helpers | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | # define OSSL_SAFE_MATH_NEGS(type_name, type, min) \
 | 
					
						
							|  |  |  |     static ossl_inline ossl_unused type safe_neg_ ## type_name(type a,       \ | 
					
						
							|  |  |  |                                                                int *err)     \ | 
					
						
							|  |  |  |     {                                                                        \ | 
					
						
							|  |  |  |         if (a != min)                                                        \ | 
					
						
							|  |  |  |             return -a;                                                       \ | 
					
						
							|  |  |  |         *err |= 1;                                                           \ | 
					
						
							|  |  |  |         return min;                                                          \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # define OSSL_SAFE_MATH_NEGU(type_name, type) \
 | 
					
						
							|  |  |  |     static ossl_inline ossl_unused type safe_neg_ ## type_name(type a,       \ | 
					
						
							|  |  |  |                                                                int *err)     \ | 
					
						
							|  |  |  |     {                                                                        \ | 
					
						
							|  |  |  |         if (a == 0)                                                          \ | 
					
						
							|  |  |  |             return a;                                                        \ | 
					
						
							|  |  |  |         *err |= 1;                                                           \ | 
					
						
							|  |  |  |         return 1 + ~a;                                                       \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Safe absolute value helpers | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | # define OSSL_SAFE_MATH_ABSS(type_name, type, min) \
 | 
					
						
							|  |  |  |     static ossl_inline ossl_unused type safe_abs_ ## type_name(type a,       \ | 
					
						
							|  |  |  |                                                                int *err)     \ | 
					
						
							|  |  |  |     {                                                                        \ | 
					
						
							|  |  |  |         if (a != min)                                                        \ | 
					
						
							|  |  |  |             return a < 0 ? -a : a;                                           \ | 
					
						
							|  |  |  |         *err |= 1;                                                           \ | 
					
						
							|  |  |  |         return min;                                                          \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # define OSSL_SAFE_MATH_ABSU(type_name, type) \
 | 
					
						
							|  |  |  |     static ossl_inline ossl_unused type safe_abs_ ## type_name(type a,       \ | 
					
						
							|  |  |  |                                                                int *err)     \ | 
					
						
							|  |  |  |     {                                                                        \ | 
					
						
							|  |  |  |         return a;                                                            \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Safe fused multiply divide helpers | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * These are a bit obscure: | 
					
						
							|  |  |  |  *    . They begin by checking the denominator for zero and getting rid of this | 
					
						
							|  |  |  |  *      corner case. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *    . Second is an attempt to do the multiplication directly, if it doesn't | 
					
						
							|  |  |  |  *      overflow, the quotient is returned (for signed values there is a | 
					
						
							|  |  |  |  *      potential problem here which isn't present for unsigned). | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *    . Finally, the multiplication/division is transformed so that the larger | 
					
						
							|  |  |  |  *      of the numerators is divided first.  This requires a remainder | 
					
						
							|  |  |  |  *      correction: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *          a b / c = (a / c) b + (a mod c) b / c, where a > b | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *      The individual operations need to be overflow checked (again signed | 
					
						
							|  |  |  |  *      being more problematic). | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The algorithm used is not perfect but it should be "good enough". | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | # define OSSL_SAFE_MATH_MULDIVS(type_name, type, max) \
 | 
					
						
							|  |  |  |     static ossl_inline ossl_unused type safe_muldiv_ ## type_name(type a,    \ | 
					
						
							|  |  |  |                                                                   type b,    \ | 
					
						
							|  |  |  |                                                                   type c,    \ | 
					
						
							|  |  |  |                                                                   int *err)  \ | 
					
						
							|  |  |  |     {                                                                        \ | 
					
						
							|  |  |  |         int e2 = 0;                                                          \ | 
					
						
							| 
									
										
										
										
											2022-08-31 14:15:44 +08:00
										 |  |  |         type q, r, x, y;                                                     \ | 
					
						
							| 
									
										
										
										
											2021-10-28 07:20:03 +08:00
										 |  |  |                                                                              \ | 
					
						
							|  |  |  |         if (c == 0) {                                                        \ | 
					
						
							|  |  |  |             *err |= 1;                                                       \ | 
					
						
							|  |  |  |             return a == 0 || b == 0 ? 0 : max;                               \ | 
					
						
							|  |  |  |         }                                                                    \ | 
					
						
							|  |  |  |         x = safe_mul_ ## type_name(a, b, &e2);                               \ | 
					
						
							|  |  |  |         if (!e2)                                                             \ | 
					
						
							|  |  |  |             return safe_div_ ## type_name(x, c, err);                        \ | 
					
						
							|  |  |  |         if (b > a) {                                                         \ | 
					
						
							|  |  |  |             x = b;                                                           \ | 
					
						
							|  |  |  |             b = a;                                                           \ | 
					
						
							|  |  |  |             a = x;                                                           \ | 
					
						
							|  |  |  |         }                                                                    \ | 
					
						
							|  |  |  |         q = safe_div_ ## type_name(a, c, err);                               \ | 
					
						
							|  |  |  |         r = safe_mod_ ## type_name(a, c, err);                               \ | 
					
						
							|  |  |  |         x = safe_mul_ ## type_name(r, b, err);                               \ | 
					
						
							|  |  |  |         y = safe_mul_ ## type_name(q, b, err);                               \ | 
					
						
							|  |  |  |         q = safe_div_ ## type_name(x, c, err);                               \ | 
					
						
							|  |  |  |         return safe_add_ ## type_name(y, q, err);                            \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # define OSSL_SAFE_MATH_MULDIVU(type_name, type, max) \
 | 
					
						
							|  |  |  |     static ossl_inline ossl_unused type safe_muldiv_ ## type_name(type a,    \ | 
					
						
							|  |  |  |                                                                   type b,    \ | 
					
						
							|  |  |  |                                                                   type c,    \ | 
					
						
							|  |  |  |                                                                   int *err)  \ | 
					
						
							|  |  |  |     {                                                                        \ | 
					
						
							|  |  |  |         int e2 = 0;                                                          \ | 
					
						
							|  |  |  |         type x, y;                                                           \ | 
					
						
							|  |  |  |                                                                              \ | 
					
						
							|  |  |  |         if (c == 0) {                                                        \ | 
					
						
							|  |  |  |             *err |= 1;                                                       \ | 
					
						
							|  |  |  |             return a == 0 || b == 0 ? 0 : max;                               \ | 
					
						
							|  |  |  |         }                                                                    \ | 
					
						
							|  |  |  |         x = safe_mul_ ## type_name(a, b, &e2);                               \ | 
					
						
							|  |  |  |         if (!e2)                                                             \ | 
					
						
							|  |  |  |             return x / c;                                                    \ | 
					
						
							|  |  |  |         if (b > a) {                                                         \ | 
					
						
							|  |  |  |             x = b;                                                           \ | 
					
						
							|  |  |  |             b = a;                                                           \ | 
					
						
							|  |  |  |             a = x;                                                           \ | 
					
						
							|  |  |  |         }                                                                    \ | 
					
						
							|  |  |  |         x = safe_mul_ ## type_name(a % c, b, err);                           \ | 
					
						
							|  |  |  |         y = safe_mul_ ## type_name(a / c, b, err);                           \ | 
					
						
							|  |  |  |         return safe_add_ ## type_name(y, x / c, err);                        \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-15 11:19:07 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Calculate a / b rounding up: | 
					
						
							|  |  |  |  *     i.e. a / b + (a % b != 0) | 
					
						
							|  |  |  |  * Which is usually (less safely) converted to (a + b - 1) / b | 
					
						
							|  |  |  |  * If you *know* that b != 0, then it's safe to ignore err. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #define OSSL_SAFE_MATH_DIV_ROUND_UP(type_name, type, max) \
 | 
					
						
							|  |  |  |     static ossl_inline ossl_unused type safe_div_round_up_ ## type_name      \ | 
					
						
							|  |  |  |         (type a, type b, int *errp)                                          \ | 
					
						
							|  |  |  |     {                                                                        \ | 
					
						
							|  |  |  |         type x;                                                              \ | 
					
						
							|  |  |  |         int *err, err_local = 0;                                             \ | 
					
						
							|  |  |  |                                                                              \ | 
					
						
							|  |  |  |         /* Allow errors to be ignored by callers */                          \ | 
					
						
							|  |  |  |         err = errp != NULL ? errp : &err_local;                              \ | 
					
						
							|  |  |  |         /* Fast path, both positive */                                       \ | 
					
						
							|  |  |  |         if (b > 0 && a > 0) {                                                \ | 
					
						
							|  |  |  |             /* Faster path: no overflow concerns */                          \ | 
					
						
							|  |  |  |             if (a < max - b)                                                 \ | 
					
						
							|  |  |  |                 return (a + b - 1) / b;                                      \ | 
					
						
							|  |  |  |             return a / b + (a % b != 0);                                     \ | 
					
						
							|  |  |  |         }                                                                    \ | 
					
						
							|  |  |  |         if (b == 0) {                                                        \ | 
					
						
							|  |  |  |             *err |= 1;                                                       \ | 
					
						
							|  |  |  |             return a == 0 ? 0 : max;                                         \ | 
					
						
							|  |  |  |         }                                                                    \ | 
					
						
							|  |  |  |         if (a == 0)                                                          \ | 
					
						
							|  |  |  |             return 0;                                                        \ | 
					
						
							|  |  |  |         /* Rather slow path because there are negatives involved */          \ | 
					
						
							|  |  |  |         x = safe_mod_ ## type_name(a, b, err);                               \ | 
					
						
							|  |  |  |         return safe_add_ ## type_name(safe_div_ ## type_name(a, b, err),     \ | 
					
						
							|  |  |  |                                       x != 0, err);                          \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-28 07:20:03 +08:00
										 |  |  | /* Calculate ranges of types */ | 
					
						
							|  |  |  | # define OSSL_SAFE_MATH_MINS(type) ((type)1 << (sizeof(type) * 8 - 1))
 | 
					
						
							|  |  |  | # define OSSL_SAFE_MATH_MAXS(type) (~OSSL_SAFE_MATH_MINS(type))
 | 
					
						
							|  |  |  | # define OSSL_SAFE_MATH_MAXU(type) (~(type)0)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Wrapper macros to create all the functions of a given type | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | # define OSSL_SAFE_MATH_SIGNED(type_name, type)                         \
 | 
					
						
							|  |  |  |     OSSL_SAFE_MATH_ADDS(type_name, type, OSSL_SAFE_MATH_MINS(type),     \ | 
					
						
							|  |  |  |                         OSSL_SAFE_MATH_MAXS(type))                      \ | 
					
						
							|  |  |  |     OSSL_SAFE_MATH_SUBS(type_name, type, OSSL_SAFE_MATH_MINS(type),     \ | 
					
						
							|  |  |  |                         OSSL_SAFE_MATH_MAXS(type))                      \ | 
					
						
							|  |  |  |     OSSL_SAFE_MATH_MULS(type_name, type, OSSL_SAFE_MATH_MINS(type),     \ | 
					
						
							|  |  |  |                         OSSL_SAFE_MATH_MAXS(type))                      \ | 
					
						
							|  |  |  |     OSSL_SAFE_MATH_DIVS(type_name, type, OSSL_SAFE_MATH_MINS(type),     \ | 
					
						
							|  |  |  |                         OSSL_SAFE_MATH_MAXS(type))                      \ | 
					
						
							|  |  |  |     OSSL_SAFE_MATH_MODS(type_name, type, OSSL_SAFE_MATH_MINS(type),     \ | 
					
						
							|  |  |  |                         OSSL_SAFE_MATH_MAXS(type))                      \ | 
					
						
							| 
									
										
										
										
											2022-03-15 11:19:07 +08:00
										 |  |  |     OSSL_SAFE_MATH_DIV_ROUND_UP(type_name, type,                        \ | 
					
						
							|  |  |  |                                 OSSL_SAFE_MATH_MAXS(type))              \ | 
					
						
							| 
									
										
										
										
											2021-10-28 07:20:03 +08:00
										 |  |  |     OSSL_SAFE_MATH_MULDIVS(type_name, type, OSSL_SAFE_MATH_MAXS(type))  \ | 
					
						
							|  |  |  |     OSSL_SAFE_MATH_NEGS(type_name, type, OSSL_SAFE_MATH_MINS(type))     \ | 
					
						
							|  |  |  |     OSSL_SAFE_MATH_ABSS(type_name, type, OSSL_SAFE_MATH_MINS(type)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # define OSSL_SAFE_MATH_UNSIGNED(type_name, type) \
 | 
					
						
							|  |  |  |     OSSL_SAFE_MATH_ADDU(type_name, type, OSSL_SAFE_MATH_MAXU(type))     \ | 
					
						
							|  |  |  |     OSSL_SAFE_MATH_SUBU(type_name, type)                                \ | 
					
						
							|  |  |  |     OSSL_SAFE_MATH_MULU(type_name, type, OSSL_SAFE_MATH_MAXU(type))     \ | 
					
						
							|  |  |  |     OSSL_SAFE_MATH_DIVU(type_name, type, OSSL_SAFE_MATH_MAXU(type))     \ | 
					
						
							|  |  |  |     OSSL_SAFE_MATH_MODU(type_name, type)                                \ | 
					
						
							| 
									
										
										
										
											2022-03-15 11:19:07 +08:00
										 |  |  |     OSSL_SAFE_MATH_DIV_ROUND_UP(type_name, type,                        \ | 
					
						
							|  |  |  |                                 OSSL_SAFE_MATH_MAXU(type))              \ | 
					
						
							| 
									
										
										
										
											2021-10-28 07:20:03 +08:00
										 |  |  |     OSSL_SAFE_MATH_MULDIVU(type_name, type, OSSL_SAFE_MATH_MAXU(type))  \ | 
					
						
							|  |  |  |     OSSL_SAFE_MATH_NEGU(type_name, type)                                \ | 
					
						
							|  |  |  |     OSSL_SAFE_MATH_ABSU(type_name, type) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif                          /* OSSL_INTERNAL_SAFE_MATH_H */
 |