]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libstrongswan/utils/utils/memory.h
Update copyright headers after acquisition by secunet
[thirdparty/strongswan.git] / src / libstrongswan / utils / utils / memory.h
1 /*
2 * Copyright (C) 2008-2014 Tobias Brunner
3 * Copyright (C) 2008 Martin Willi
4 *
5 * Copyright (C) secunet Security Networks AG
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18 /**
19 * @defgroup memory_i memory
20 * @{ @ingroup utils_i
21 */
22
23 #ifndef MEMORY_H_
24 #define MEMORY_H_
25
26 #ifdef HAVE_EXPLICIT_BZERO
27 #include <string.h>
28 #endif
29
30 /**
31 * Helper function that compares two binary blobs for equality
32 */
33 static inline bool memeq(const void *x, const void *y, size_t len)
34 {
35 return memcmp(x, y, len) == 0;
36 }
37
38 /**
39 * Same as memeq(), but with a constant runtime, safe for cryptographic use.
40 */
41 bool memeq_const(const void *x, const void *y, size_t len);
42
43 /**
44 * Calling memcpy() with NULL pointers, even with n == 0, results in undefined
45 * behavior according to the C standard. This version is guaranteed to not
46 * access the pointers if n is 0.
47 */
48 static inline void *memcpy_noop(void *dst, const void *src, size_t n)
49 {
50 return n ? memcpy(dst, src, n) : dst;
51 }
52 #ifdef memcpy
53 # undef memcpy
54 #endif
55 #define memcpy(d,s,n) memcpy_noop(d,s,n)
56
57 /**
58 * Calling memmove() with NULL pointers, even with n == 0, results in undefined
59 * behavior according to the C standard. This version is guaranteed to not
60 * access the pointers if n is 0.
61 */
62 static inline void *memmove_noop(void *dst, const void *src, size_t n)
63 {
64 return n ? memmove(dst, src, n) : dst;
65 }
66 #ifdef memmove
67 # undef memmove
68 #endif
69 #define memmove(d,s,n) memmove_noop(d,s,n)
70
71 /**
72 * Calling memset() with a NULL pointer, even with n == 0, results in undefined
73 * behavior according to the C standard. This version is guaranteed to not
74 * access the pointer if n is 0.
75 */
76 static inline void *memset_noop(void *s, int c, size_t n)
77 {
78 return n ? memset(s, c, n) : s;
79 }
80 #ifdef memset
81 # undef memset
82 #endif
83 #define memset(s,c,n) memset_noop(s,c,n)
84
85 /**
86 * Same as memcpy, but XORs src into dst instead of copy
87 */
88 void memxor(uint8_t dest[], const uint8_t src[], size_t n);
89
90 #ifdef HAVE_EXPLICIT_BZERO
91 static inline void memwipe(void *ptr, size_t n)
92 {
93 if (ptr)
94 {
95 explicit_bzero(ptr, n);
96 }
97 }
98 #else /* HAVE_EXPLICIT_BZERO */
99 /**
100 * Safely overwrite n bytes of memory at ptr with zero, non-inlining variant.
101 */
102 void memwipe_noinline(void *ptr, size_t n);
103
104 /**
105 * Safely overwrite n bytes of memory at ptr with zero, inlining variant.
106 */
107 static inline void memwipe_inline(void *ptr, size_t n)
108 {
109 volatile char *c = (volatile char*)ptr;
110 size_t m, i;
111
112 /* byte wise until long aligned */
113 for (i = 0; (uintptr_t)&c[i] % sizeof(long) && i < n; i++)
114 {
115 c[i] = 0;
116 }
117 /* word wise */
118 if (n >= sizeof(long))
119 {
120 for (m = n - sizeof(long); i <= m; i += sizeof(long))
121 {
122 *(volatile long*)&c[i] = 0;
123 }
124 }
125 /* byte wise of the rest */
126 for (; i < n; i++)
127 {
128 c[i] = 0;
129 }
130 }
131
132 /**
133 * Safely overwrite n bytes of memory at ptr with zero, auto-inlining variant.
134 */
135 static inline void memwipe(void *ptr, size_t n)
136 {
137 if (!ptr)
138 {
139 return;
140 }
141 if (__builtin_constant_p(n))
142 {
143 memwipe_inline(ptr, n);
144 }
145 else
146 {
147 memwipe_noinline(ptr, n);
148 }
149 }
150 #endif /* HAVE_EXPLICIT_BZERO */
151
152 /**
153 * A variant of strstr with the characteristics of memchr, where haystack is not
154 * a null-terminated string but simply a memory area of length n.
155 */
156 void *memstr(const void *haystack, const char *needle, size_t n);
157
158 /**
159 * Replacement for memrchr(3) if it is not provided by the C library.
160 *
161 * @param s start of the memory area to search
162 * @param c character to search
163 * @param n length of memory area to search
164 * @return pointer to the found character or NULL
165 */
166 void *utils_memrchr(const void *s, int c, size_t n);
167
168 #ifndef HAVE_MEMRCHR
169 #define memrchr(s,c,n) utils_memrchr(s,c,n)
170 #endif
171
172 #ifndef HAVE_FMEMOPEN
173 # ifdef HAVE_FUNOPEN
174 # define HAVE_FMEMOPEN
175 # define HAVE_FMEMOPEN_FALLBACK
176 # include <stdio.h>
177 /**
178 * fmemopen(3) fallback using BSD funopen.
179 *
180 * We could also provide one using fopencookie(), but should we have it we
181 * most likely have fmemopen().
182 *
183 * fseek() is currently not supported.
184 */
185 FILE *fmemopen(void *buf, size_t size, const char *mode);
186 # endif /* FUNOPEN */
187 #endif /* FMEMOPEN */
188
189 /**
190 * printf hook for memory areas.
191 *
192 * Arguments are:
193 * u_char *ptr, u_int len
194 */
195 int mem_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
196 const void *const *args);
197
198 #endif /** MEMORY_H_ @} */