1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright (C) 2016 The Android Open Source Project
4  */
5 
6 #include "avb_util.h"
7 #include <log.h>
8 #include <malloc.h>
9 
10 #include <stdarg.h>
11 
avb_be32toh(uint32_t in)12 uint32_t avb_be32toh(uint32_t in) {
13   uint8_t* d = (uint8_t*)&in;
14   uint32_t ret;
15   ret = ((uint32_t)d[0]) << 24;
16   ret |= ((uint32_t)d[1]) << 16;
17   ret |= ((uint32_t)d[2]) << 8;
18   ret |= ((uint32_t)d[3]);
19   return ret;
20 }
21 
avb_be64toh(uint64_t in)22 uint64_t avb_be64toh(uint64_t in) {
23   uint8_t* d = (uint8_t*)&in;
24   uint64_t ret;
25   ret = ((uint64_t)d[0]) << 56;
26   ret |= ((uint64_t)d[1]) << 48;
27   ret |= ((uint64_t)d[2]) << 40;
28   ret |= ((uint64_t)d[3]) << 32;
29   ret |= ((uint64_t)d[4]) << 24;
30   ret |= ((uint64_t)d[5]) << 16;
31   ret |= ((uint64_t)d[6]) << 8;
32   ret |= ((uint64_t)d[7]);
33   return ret;
34 }
35 
36 /* Converts a 32-bit unsigned integer from host to big-endian byte order. */
avb_htobe32(uint32_t in)37 uint32_t avb_htobe32(uint32_t in) {
38   union {
39     uint32_t word;
40     uint8_t bytes[4];
41   } ret;
42   ret.bytes[0] = (in >> 24) & 0xff;
43   ret.bytes[1] = (in >> 16) & 0xff;
44   ret.bytes[2] = (in >> 8) & 0xff;
45   ret.bytes[3] = in & 0xff;
46   return ret.word;
47 }
48 
49 /* Converts a 64-bit unsigned integer from host to big-endian byte order. */
avb_htobe64(uint64_t in)50 uint64_t avb_htobe64(uint64_t in) {
51   union {
52     uint64_t word;
53     uint8_t bytes[8];
54   } ret;
55   ret.bytes[0] = (in >> 56) & 0xff;
56   ret.bytes[1] = (in >> 48) & 0xff;
57   ret.bytes[2] = (in >> 40) & 0xff;
58   ret.bytes[3] = (in >> 32) & 0xff;
59   ret.bytes[4] = (in >> 24) & 0xff;
60   ret.bytes[5] = (in >> 16) & 0xff;
61   ret.bytes[6] = (in >> 8) & 0xff;
62   ret.bytes[7] = in & 0xff;
63   return ret.word;
64 }
65 
avb_safe_memcmp(const void * s1,const void * s2,size_t n)66 int avb_safe_memcmp(const void* s1, const void* s2, size_t n) {
67   const unsigned char* us1 = s1;
68   const unsigned char* us2 = s2;
69   int result = 0;
70 
71   if (0 == n) {
72     return 0;
73   }
74 
75   /*
76    * Code snippet without data-dependent branch due to Nate Lawson
77    * (nate@root.org) of Root Labs.
78    */
79   while (n--) {
80     result |= *us1++ ^ *us2++;
81   }
82 
83   return result != 0;
84 }
85 
avb_safe_add_to(uint64_t * value,uint64_t value_to_add)86 bool avb_safe_add_to(uint64_t* value, uint64_t value_to_add) {
87   uint64_t original_value;
88 
89   avb_assert(value != NULL);
90 
91   original_value = *value;
92 
93   *value += value_to_add;
94   if (*value < original_value) {
95     avb_error("Overflow when adding values.\n");
96     return false;
97   }
98 
99   return true;
100 }
101 
avb_safe_add(uint64_t * out_result,uint64_t a,uint64_t b)102 bool avb_safe_add(uint64_t* out_result, uint64_t a, uint64_t b) {
103   uint64_t dummy;
104   if (out_result == NULL) {
105     out_result = &dummy;
106   }
107   *out_result = a;
108   return avb_safe_add_to(out_result, b);
109 }
110 
avb_validate_utf8(const uint8_t * data,size_t num_bytes)111 bool avb_validate_utf8(const uint8_t* data, size_t num_bytes) {
112   size_t n;
113   unsigned int num_cc;
114 
115   for (n = 0, num_cc = 0; n < num_bytes; n++) {
116     uint8_t c = data[n];
117 
118     if (num_cc > 0) {
119       if ((c & (0x80 | 0x40)) == 0x80) {
120         /* 10xx xxxx */
121       } else {
122         goto fail;
123       }
124       num_cc--;
125     } else {
126       if (c < 0x80) {
127         num_cc = 0;
128       } else if ((c & (0x80 | 0x40 | 0x20)) == (0x80 | 0x40)) {
129         /* 110x xxxx */
130         num_cc = 1;
131       } else if ((c & (0x80 | 0x40 | 0x20 | 0x10)) == (0x80 | 0x40 | 0x20)) {
132         /* 1110 xxxx */
133         num_cc = 2;
134       } else if ((c & (0x80 | 0x40 | 0x20 | 0x10 | 0x08)) ==
135                  (0x80 | 0x40 | 0x20 | 0x10)) {
136         /* 1111 0xxx */
137         num_cc = 3;
138       } else {
139         goto fail;
140       }
141     }
142   }
143 
144   if (num_cc != 0) {
145     goto fail;
146   }
147 
148   return true;
149 
150 fail:
151   return false;
152 }
153 
avb_str_concat(char * buf,size_t buf_size,const char * str1,size_t str1_len,const char * str2,size_t str2_len)154 bool avb_str_concat(char* buf,
155                     size_t buf_size,
156                     const char* str1,
157                     size_t str1_len,
158                     const char* str2,
159                     size_t str2_len) {
160   uint64_t combined_len;
161 
162   if (!avb_safe_add(&combined_len, str1_len, str2_len)) {
163     avb_error("Overflow when adding string sizes.\n");
164     return false;
165   }
166 
167   if (combined_len > buf_size - 1) {
168     avb_error("Insufficient buffer space.\n");
169     return false;
170   }
171 
172   avb_memcpy(buf, str1, str1_len);
173   avb_memcpy(buf + str1_len, str2, str2_len);
174   buf[combined_len] = '\0';
175 
176   return true;
177 }
178 
avb_malloc(size_t size)179 void* avb_malloc(size_t size) {
180   void* ret = avb_malloc_(size);
181   if (ret == NULL) {
182     avb_error("Failed to allocate memory.\n");
183     return NULL;
184   }
185   return ret;
186 }
187 
avb_calloc(size_t size)188 void* avb_calloc(size_t size) {
189   void* ret = avb_malloc(size);
190   if (ret == NULL) {
191     return NULL;
192   }
193 
194   avb_memset(ret, '\0', size);
195   return ret;
196 }
197 
avb_strdup(const char * str)198 char* avb_strdup(const char* str) {
199   size_t len = avb_strlen(str);
200   char* ret = avb_malloc(len + 1);
201   if (ret == NULL) {
202     return NULL;
203   }
204 
205   avb_memcpy(ret, str, len);
206   ret[len] = '\0';
207 
208   return ret;
209 }
210 
avb_strstr(const char * haystack,const char * needle)211 const char* avb_strstr(const char* haystack, const char* needle) {
212   size_t n, m;
213 
214   /* Look through |haystack| and check if the first character of
215    * |needle| matches. If so, check the rest of |needle|.
216    */
217   for (n = 0; haystack[n] != '\0'; n++) {
218     if (haystack[n] != needle[0]) {
219       continue;
220     }
221 
222     for (m = 1;; m++) {
223       if (needle[m] == '\0') {
224         return haystack + n;
225       }
226 
227       if (haystack[n + m] != needle[m]) {
228         break;
229       }
230     }
231   }
232 
233   return NULL;
234 }
235 
avb_strv_find_str(const char * const * strings,const char * str,size_t str_size)236 const char* avb_strv_find_str(const char* const* strings,
237                               const char* str,
238                               size_t str_size) {
239   size_t n;
240   for (n = 0; strings[n] != NULL; n++) {
241     if (avb_strlen(strings[n]) == str_size &&
242         avb_memcmp(strings[n], str, str_size) == 0) {
243       return strings[n];
244     }
245   }
246   return NULL;
247 }
248 
avb_replace(const char * str,const char * search,const char * replace)249 char* avb_replace(const char* str, const char* search, const char* replace) {
250   char* ret = NULL;
251   size_t ret_len = 0;
252   size_t search_len, replace_len;
253   const char* str_after_last_replace;
254 
255   search_len = avb_strlen(search);
256   replace_len = avb_strlen(replace);
257 
258   str_after_last_replace = str;
259   while (*str != '\0') {
260     const char* s;
261     size_t num_before;
262     size_t num_new;
263 
264     s = avb_strstr(str, search);
265     if (s == NULL) {
266       break;
267     }
268 
269     num_before = s - str;
270 
271     if (ret == NULL) {
272       num_new = num_before + replace_len + 1;
273       ret = avb_malloc(num_new);
274       if (ret == NULL) {
275         goto out;
276       }
277       avb_memcpy(ret, str, num_before);
278       avb_memcpy(ret + num_before, replace, replace_len);
279       ret[num_new - 1] = '\0';
280       ret_len = num_new - 1;
281     } else {
282       char* new_str;
283       num_new = ret_len + num_before + replace_len + 1;
284       new_str = avb_malloc(num_new);
285       if (new_str == NULL) {
286         goto out;
287       }
288       avb_memcpy(new_str, ret, ret_len);
289       avb_memcpy(new_str + ret_len, str, num_before);
290       avb_memcpy(new_str + ret_len + num_before, replace, replace_len);
291       new_str[num_new - 1] = '\0';
292       avb_free(ret);
293       ret = new_str;
294       ret_len = num_new - 1;
295     }
296 
297     str = s + search_len;
298     str_after_last_replace = str;
299   }
300 
301   if (ret == NULL) {
302     ret = avb_strdup(str_after_last_replace);
303     if (ret == NULL) {
304       goto out;
305     }
306   } else {
307     size_t num_remaining = avb_strlen(str_after_last_replace);
308     size_t num_new = ret_len + num_remaining + 1;
309     char* new_str = avb_malloc(num_new);
310     if (new_str == NULL) {
311       goto out;
312     }
313     avb_memcpy(new_str, ret, ret_len);
314     avb_memcpy(new_str + ret_len, str_after_last_replace, num_remaining);
315     new_str[num_new - 1] = '\0';
316     avb_free(ret);
317     ret = new_str;
318     ret_len = num_new - 1;
319   }
320 
321 out:
322   return ret;
323 }
324 
325 /* We only support a limited amount of strings in avb_strdupv(). */
326 #define AVB_STRDUPV_MAX_NUM_STRINGS 32
327 
avb_strdupv(const char * str,...)328 char* avb_strdupv(const char* str, ...) {
329   va_list ap;
330   const char* strings[AVB_STRDUPV_MAX_NUM_STRINGS];
331   size_t lengths[AVB_STRDUPV_MAX_NUM_STRINGS];
332   size_t num_strings, n;
333   uint64_t total_length;
334   char *ret = NULL, *dest;
335 
336   num_strings = 0;
337   total_length = 0;
338   va_start(ap, str);
339   do {
340     size_t str_len = avb_strlen(str);
341     strings[num_strings] = str;
342     lengths[num_strings] = str_len;
343     if (!avb_safe_add_to(&total_length, str_len)) {
344       avb_fatal("Overflow while determining total length.\n");
345       break;
346     }
347     num_strings++;
348     if (num_strings == AVB_STRDUPV_MAX_NUM_STRINGS) {
349       avb_fatal("Too many strings passed.\n");
350       break;
351     }
352     str = va_arg(ap, const char*);
353   } while (str != NULL);
354   va_end(ap);
355 
356   ret = avb_malloc(total_length + 1);
357   if (ret == NULL) {
358     goto out;
359   }
360 
361   dest = ret;
362   for (n = 0; n < num_strings; n++) {
363     avb_memcpy(dest, strings[n], lengths[n]);
364     dest += lengths[n];
365   }
366   *dest = '\0';
367   avb_assert(dest == ret + total_length);
368 
369 out:
370   return ret;
371 }
372 
avb_basename(const char * str)373 const char* avb_basename(const char* str) {
374   int64_t n;
375   size_t len;
376 
377   len = avb_strlen(str);
378   if (len >= 2) {
379     for (n = len - 2; n >= 0; n--) {
380       if (str[n] == '/') {
381         return str + n + 1;
382       }
383     }
384   }
385   return str;
386 }
387 
avb_uppercase(char * str)388 void avb_uppercase(char* str) {
389   size_t i;
390   for (i = 0; str[i] != '\0'; ++i) {
391     if (str[i] <= 0x7A && str[i] >= 0x61) {
392       str[i] -= 0x20;
393     }
394   }
395 }
396 
avb_bin2hex(const uint8_t * data,size_t data_len)397 char* avb_bin2hex(const uint8_t* data, size_t data_len) {
398   const char hex_digits[17] = "0123456789abcdef";
399   char* hex_data;
400   size_t n;
401 
402   hex_data = avb_malloc(data_len * 2 + 1);
403   if (hex_data == NULL) {
404     return NULL;
405   }
406 
407   for (n = 0; n < data_len; n++) {
408     hex_data[n * 2] = hex_digits[data[n] >> 4];
409     hex_data[n * 2 + 1] = hex_digits[data[n] & 0x0f];
410   }
411   hex_data[n * 2] = '\0';
412   return hex_data;
413 }
414