1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Copyright (C) 2016 The Android Open Source Project
4  */
5 
6 #if !defined(AVB_INSIDE_LIBAVB_H) && !defined(AVB_COMPILATION)
7 #error "Never include this file directly, include libavb.h instead."
8 #endif
9 
10 #ifndef AVB_UTIL_H_
11 #define AVB_UTIL_H_
12 
13 #include "avb_sysdeps.h"
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 #define AVB_STRINGIFY(x) #x
20 #define AVB_TO_STRING(x) AVB_STRINGIFY(x)
21 
22 #ifdef AVB_ENABLE_DEBUG
23 /* Aborts the program if |expr| is false.
24  *
25  * This has no effect unless AVB_ENABLE_DEBUG is defined.
26  */
27 #define avb_assert(expr)                     \
28   do {                                       \
29     if (!(expr)) {                           \
30       avb_fatal("assert fail: " #expr "\n"); \
31     }                                        \
32   } while (0)
33 #else
34 #define avb_assert(expr)
35 #endif
36 
37 /* Aborts the program if reached.
38  *
39  * This has no effect unless AVB_ENABLE_DEBUG is defined.
40  */
41 #ifdef AVB_ENABLE_DEBUG
42 #define avb_assert_not_reached()         \
43   do {                                   \
44     avb_fatal("assert_not_reached()\n"); \
45   } while (0)
46 #else
47 #define avb_assert_not_reached()
48 #endif
49 
50 /* Aborts the program if |addr| is not word-aligned.
51  *
52  * This has no effect unless AVB_ENABLE_DEBUG is defined.
53  */
54 #define avb_assert_aligned(addr) \
55   avb_assert((((uintptr_t)addr) & (AVB_ALIGNMENT_SIZE - 1)) == 0)
56 
57 #ifdef AVB_ENABLE_DEBUG
58 /* Print functions, used for diagnostics.
59  *
60  * These have no effect unless AVB_ENABLE_DEBUG is defined.
61  */
62 #define avb_debug(message)              \
63   do {                                  \
64     avb_printv(avb_basename(__FILE__),  \
65                ":",                     \
66                AVB_TO_STRING(__LINE__), \
67                ": DEBUG: ",             \
68                message,                 \
69                NULL);                   \
70   } while (0)
71 #define avb_debugv(message, ...)        \
72   do {                                  \
73     avb_printv(avb_basename(__FILE__),  \
74                ":",                     \
75                AVB_TO_STRING(__LINE__), \
76                ": DEBUG: ",             \
77                message,                 \
78                ##__VA_ARGS__);          \
79   } while (0)
80 #else
81 #define avb_debug(message)
82 #define avb_debugv(message, ...)
83 #endif
84 
85 /* Prints out a message. This is typically used if a runtime-error
86  * occurs.
87  */
88 #define avb_error(message)              \
89   do {                                  \
90     avb_printv(avb_basename(__FILE__),  \
91                ":",                     \
92                AVB_TO_STRING(__LINE__), \
93                ": ERROR: ",             \
94                message,                 \
95                NULL);                   \
96   } while (0)
97 #define avb_errorv(message, ...)        \
98   do {                                  \
99     avb_printv(avb_basename(__FILE__),  \
100                ":",                     \
101                AVB_TO_STRING(__LINE__), \
102                ": ERROR: ",             \
103                message,                 \
104                ##__VA_ARGS__);          \
105   } while (0)
106 
107 /* Prints out a message and calls avb_abort().
108  */
109 #define avb_fatal(message)              \
110   do {                                  \
111     avb_printv(avb_basename(__FILE__),  \
112                ":",                     \
113                AVB_TO_STRING(__LINE__), \
114                ": FATAL: ",             \
115                message,                 \
116                NULL);                   \
117     avb_abort();                        \
118   } while (0)
119 #define avb_fatalv(message, ...)        \
120   do {                                  \
121     avb_printv(avb_basename(__FILE__),  \
122                ":",                     \
123                AVB_TO_STRING(__LINE__), \
124                ": FATAL: ",             \
125                message,                 \
126                ##__VA_ARGS__);          \
127     avb_abort();                        \
128   } while (0)
129 
130 /* Converts a 32-bit unsigned integer from big-endian to host byte order. */
131 uint32_t avb_be32toh(uint32_t in) AVB_ATTR_WARN_UNUSED_RESULT;
132 
133 /* Converts a 64-bit unsigned integer from big-endian to host byte order. */
134 uint64_t avb_be64toh(uint64_t in) AVB_ATTR_WARN_UNUSED_RESULT;
135 
136 /* Converts a 32-bit unsigned integer from host to big-endian byte order. */
137 uint32_t avb_htobe32(uint32_t in) AVB_ATTR_WARN_UNUSED_RESULT;
138 
139 /* Converts a 64-bit unsigned integer from host to big-endian byte order. */
140 uint64_t avb_htobe64(uint64_t in) AVB_ATTR_WARN_UNUSED_RESULT;
141 
142 /* Compare |n| bytes starting at |s1| with |s2| and return 0 if they
143  * match, 1 if they don't.  Returns 0 if |n|==0, since no bytes
144  * mismatched.
145  *
146  * Time taken to perform the comparison is only dependent on |n| and
147  * not on the relationship of the match between |s1| and |s2|.
148  *
149  * Note that unlike avb_memcmp(), this only indicates inequality, not
150  * whether |s1| is less than or greater than |s2|.
151  */
152 int avb_safe_memcmp(const void* s1,
153                     const void* s2,
154                     size_t n) AVB_ATTR_WARN_UNUSED_RESULT;
155 
156 /* Adds |value_to_add| to |value| with overflow protection.
157  *
158  * Returns false if the addition overflows, true otherwise. In either
159  * case, |value| is always modified.
160  */
161 bool avb_safe_add_to(uint64_t* value,
162                      uint64_t value_to_add) AVB_ATTR_WARN_UNUSED_RESULT;
163 
164 /* Adds |a| and |b| with overflow protection, returning the value in
165  * |out_result|.
166  *
167  * It's permissible to pass NULL for |out_result| if you just want to
168  * check that the addition would not overflow.
169  *
170  * Returns false if the addition overflows, true otherwise.
171  */
172 bool avb_safe_add(uint64_t* out_result,
173                   uint64_t a,
174                   uint64_t b) AVB_ATTR_WARN_UNUSED_RESULT;
175 
176 /* Checks if |num_bytes| data at |data| is a valid UTF-8
177  * string. Returns true if valid UTF-8, false otherwise.
178  */
179 bool avb_validate_utf8(const uint8_t* data,
180                        size_t num_bytes) AVB_ATTR_WARN_UNUSED_RESULT;
181 
182 /* Concatenates |str1| (of |str1_len| bytes) and |str2| (of |str2_len|
183  * bytes) and puts the result in |buf| which holds |buf_size|
184  * bytes. The result is also guaranteed to be NUL terminated. Fail if
185  * there is not enough room in |buf| for the resulting string plus
186  * terminating NUL byte.
187  *
188  * Returns true if the operation succeeds, false otherwise.
189  */
190 bool avb_str_concat(char* buf,
191                     size_t buf_size,
192                     const char* str1,
193                     size_t str1_len,
194                     const char* str2,
195                     size_t str2_len);
196 
197 /* Like avb_malloc_() but prints a error using avb_error() if memory
198  * allocation fails.
199  */
200 void* avb_malloc(size_t size) AVB_ATTR_WARN_UNUSED_RESULT;
201 
202 /* Like avb_malloc() but sets the memory with zeroes. */
203 void* avb_calloc(size_t size) AVB_ATTR_WARN_UNUSED_RESULT;
204 
205 /* Duplicates a NUL-terminated string. Returns NULL on OOM. */
206 char* avb_strdup(const char* str) AVB_ATTR_WARN_UNUSED_RESULT;
207 
208 /* Duplicates a NULL-terminated array of NUL-terminated strings by
209  * concatenating them. The returned string will be
210  * NUL-terminated. Returns NULL on OOM.
211  */
212 char* avb_strdupv(const char* str,
213                   ...) AVB_ATTR_WARN_UNUSED_RESULT AVB_ATTR_SENTINEL;
214 
215 /* Finds the first occurrence of |needle| in the string |haystack|
216  * where both strings are NUL-terminated strings. The terminating NUL
217  * bytes are not compared.
218  *
219  * Returns NULL if not found, otherwise points into |haystack| for the
220  * first occurrence of |needle|.
221  */
222 const char* avb_strstr(const char* haystack,
223                        const char* needle) AVB_ATTR_WARN_UNUSED_RESULT;
224 
225 /* Finds the first occurrence of |str| in the NULL-terminated string
226  * array |strings|. Each element in |strings| must be
227  * NUL-terminated. The string given by |str| need not be
228  * NUL-terminated but its size must be given in |str_size|.
229  *
230  * Returns NULL if not found, otherwise points into |strings| for the
231  * first occurrence of |str|.
232  */
233 const char* avb_strv_find_str(const char* const* strings,
234                               const char* str,
235                               size_t str_size);
236 
237 /* Replaces all occurrences of |search| with |replace| in |str|.
238  *
239  * Returns a newly allocated string or NULL if out of memory.
240  */
241 char* avb_replace(const char* str,
242                   const char* search,
243                   const char* replace) AVB_ATTR_WARN_UNUSED_RESULT;
244 
245 /* Calculates the CRC-32 for data in |buf| of size |buf_size|. */
246 uint32_t avb_crc32(const uint8_t* buf, size_t buf_size);
247 
248 /* Returns the basename of |str|. This is defined as the last path
249  * component, assuming the normal POSIX separator '/'. If there are no
250  * separators, returns |str|.
251  */
252 const char* avb_basename(const char* str);
253 
254 /* Converts any ascii lowercase characters in |str| to uppercase in-place.
255  * |str| must be NUL-terminated and valid UTF-8.
256  */
257 void avb_uppercase(char* str);
258 
259 /* Converts |data_len| bytes of |data| to hex and returns the result. Returns
260  * NULL on OOM. Caller must free the returned string with avb_free.
261  */
262 char* avb_bin2hex(const uint8_t* data, size_t data_len);
263 
264 #ifdef __cplusplus
265 }
266 #endif
267 
268 #endif /* AVB_UTIL_H_ */
269