xref: /optee_os/lib/libutils/ext/include/string_ext.h (revision 136db985e77139ce598650e6d4db8ccf68652b2a)
11bb92983SJerome Forissier /* SPDX-License-Identifier: BSD-2-Clause */
2b0104773SPascal Brand /*
3b0104773SPascal Brand  * Copyright (c) 2014, STMicroelectronics International N.V.
4b0104773SPascal Brand  */
5b0104773SPascal Brand 
6b0104773SPascal Brand /*
7b0104773SPascal Brand  * This file provides extensions for functions not defined in <string.h>
8b0104773SPascal Brand  */
9b0104773SPascal Brand 
107eaed3a3SEtienne Carriere #ifndef __STRING_EXT_H
117eaed3a3SEtienne Carriere #define __STRING_EXT_H
12b0104773SPascal Brand 
13b0104773SPascal Brand #include <stddef.h>
14b0104773SPascal Brand #include <sys/cdefs.h>
15b0104773SPascal Brand 
16b0104773SPascal Brand /*
17b0104773SPascal Brand  * Copy src to string dst of siz size.  At most siz-1 characters
18b0104773SPascal Brand  * will be copied.  Always NUL terminates (unless siz == 0).
19b0104773SPascal Brand  * Returns strlen(src); if retval >= siz, truncation occurred.
20b0104773SPascal Brand  */
21b0104773SPascal Brand size_t strlcpy(char *dst, const char *src, size_t size);
22b0104773SPascal Brand size_t strlcat(char *dst, const char *src, size_t size);
23b0104773SPascal Brand 
2448e10604SJerome Forissier /* A constant-time version of memcmp() */
25b7da54b3SJerome Forissier int consttime_memcmp(const void *p1, const void *p2, size_t nb);
26b7da54b3SJerome Forissier 
2748e10604SJerome Forissier /* Deprecated. For backward compatibility. */
buf_compare_ct(const void * s1,const void * s2,size_t n)2848e10604SJerome Forissier static inline int buf_compare_ct(const void *s1, const void *s2, size_t n)
2948e10604SJerome Forissier {
3048e10604SJerome Forissier 	return consttime_memcmp(s1, s2, n);
3148e10604SJerome Forissier }
3248e10604SJerome Forissier 
331131d3c5SVolodymyr Babchuk /* Variant of strdup() that uses nex_malloc() instead of malloc() */
341131d3c5SVolodymyr Babchuk char *nex_strdup(const char *s);
351131d3c5SVolodymyr Babchuk 
367c8b181aSJerome Forissier /*
377c8b181aSJerome Forissier  * Like memset(s, 0, count) but prevents the compiler from optimizing the call
387c8b181aSJerome Forissier  * away. Such "dead store elimination" optimizations typically occur when
397c8b181aSJerome Forissier  * clearing a *local* variable that is not used after it is cleared; but
407c8b181aSJerome Forissier  * link-time optimization (LTO) can also trigger code elimination in other
417c8b181aSJerome Forissier  * circumstances. See "Dead Store Elimination (Still) Considered Harmful" [1]
427c8b181aSJerome Forissier  * for details and examples (and note that the Cland compiler enables LTO by
437c8b181aSJerome Forissier  * default!).
447c8b181aSJerome Forissier  *
457c8b181aSJerome Forissier  * [1] https://www.usenix.org/system/files/conference/usenixsecurity17/sec17-yang.pdf
467c8b181aSJerome Forissier  *
477c8b181aSJerome Forissier  * Practically speaking:
487c8b181aSJerome Forissier  *
497c8b181aSJerome Forissier  * - Use memzero_explicit() to *clear* (as opposed to initialize) *sensitive*
507c8b181aSJerome Forissier  *   data (such as keys, passwords, cryptographic state);
517c8b181aSJerome Forissier  * - Otherwise, use memset().
527c8b181aSJerome Forissier  */
537c8b181aSJerome Forissier void memzero_explicit(void *s, size_t count);
547c8b181aSJerome Forissier 
55*136db985SJens Wiklander /*
56*136db985SJens Wiklander  * ins_array_elem() - insert an element in an array
57*136db985SJens Wiklander  * @base:        start of the array
58*136db985SJens Wiklander  * @elem_count:  the number of elements in the array
59*136db985SJens Wiklander  * @elem_size:   the size of each element in the array
60*136db985SJens Wiklander  * @pos:         element position counted in units of @elem_size
61*136db985SJens Wiklander  * @elem:        pointer the the element to inser or NULL
62*136db985SJens Wiklander  *
63*136db985SJens Wiklander  * Makes room in the array at @pos by moving the element after this
64*136db985SJens Wiklander  * position one position further back.
65*136db985SJens Wiklander  *
66*136db985SJens Wiklander  * If @elem is non-NULL it's copied into the array at the indicated
67*136db985SJens Wiklander  * position.
68*136db985SJens Wiklander  *
69*136db985SJens Wiklander  * Returns a pointer to the inserted element.
70*136db985SJens Wiklander  */
71*136db985SJens Wiklander void *ins_array_elem(void *base, size_t elem_count, size_t elem_size,
72*136db985SJens Wiklander 		     size_t pos, const void *elem);
73*136db985SJens Wiklander 
74*136db985SJens Wiklander /*
75*136db985SJens Wiklander  * ins_array_elem_zero_init() - insert a zero-initialized element in an array
76*136db985SJens Wiklander  * @base:        start of the array
77*136db985SJens Wiklander  * @elem_count:  the number of elements in the array
78*136db985SJens Wiklander  * @elem_size:   the size of each element in the array
79*136db985SJens Wiklander  * @pos:         element position counted in units of @elem_size
80*136db985SJens Wiklander  *
81*136db985SJens Wiklander  * Makes room in the array at @pos by moving the element after this
82*136db985SJens Wiklander  * position one position further back. The free position is
83*136db985SJens Wiklander  * zero-initialized.
84*136db985SJens Wiklander  *
85*136db985SJens Wiklander  * Returns a pointer to the free position.
86*136db985SJens Wiklander  */
87*136db985SJens Wiklander void *ins_array_elem_zero_init(void *base, size_t elem_count, size_t elem_size,
88*136db985SJens Wiklander 			       size_t pos);
89*136db985SJens Wiklander 
90*136db985SJens Wiklander /*
91*136db985SJens Wiklander  * rem_array_elem() - remove an element from an array
92*136db985SJens Wiklander  * @base:        start of the array
93*136db985SJens Wiklander  * @elem_count:  the number of elements in the array
94*136db985SJens Wiklander  * @elem_size:   the size of each element in the array
95*136db985SJens Wiklander  * @pos:         element position counted in units of @elem_size
96*136db985SJens Wiklander  *
97*136db985SJens Wiklander  * Removes the element at @pos by advancing the element after this position
98*136db985SJens Wiklander  * to fill the space.
99*136db985SJens Wiklander  */
100*136db985SJens Wiklander void rem_array_elem(void *base, size_t elem_count, size_t elem_size,
101*136db985SJens Wiklander 		    size_t pos);
102*136db985SJens Wiklander 
103*136db985SJens Wiklander /*
104*136db985SJens Wiklander  * rem_array_elem_zero_pad() - remove an element from an array
105*136db985SJens Wiklander  * @base:        start of the array
106*136db985SJens Wiklander  * @elem_count:  the number of elements in the array
107*136db985SJens Wiklander  * @elem_size:   the size of each element in the array
108*136db985SJens Wiklander  * @pos:         element position counted in units of @elem_size
109*136db985SJens Wiklander  *
110*136db985SJens Wiklander  * Removes the element at @pos by advancing the element after this position
111*136db985SJens Wiklander  * to fill the space. The now unused element at the end of the array is
112*136db985SJens Wiklander  * zero-initialized.
113*136db985SJens Wiklander  */
114*136db985SJens Wiklander void rem_array_elem_zero_pad(void *base, size_t elem_count, size_t elem_size,
115*136db985SJens Wiklander 			     size_t pos);
116*136db985SJens Wiklander 
1177eaed3a3SEtienne Carriere #endif /* __STRING_EXT_H */
118