/src/strongswan/src/libstrongswan/utils/utils/memory.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2008-2014 Tobias Brunner |
3 | | * Copyright (C) 2005-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 | | #include <utils/utils.h> |
19 | | #include <utils/chunk.h> |
20 | | |
21 | | /** |
22 | | * Described in header. |
23 | | */ |
24 | | void memxor(uint8_t dst[], const uint8_t src[], size_t n) |
25 | 0 | { |
26 | 0 | int m, i; |
27 | | |
28 | | /* byte wise XOR until dst aligned */ |
29 | 0 | for (i = 0; (uintptr_t)&dst[i] % sizeof(long) && i < n; i++) |
30 | 0 | { |
31 | 0 | dst[i] ^= src[i]; |
32 | 0 | } |
33 | | /* try to use words if src shares an alignment with dst */ |
34 | 0 | switch (((uintptr_t)&src[i] % sizeof(long))) |
35 | 0 | { |
36 | 0 | case 0: |
37 | 0 | for (m = n - sizeof(long); i <= m; i += sizeof(long)) |
38 | 0 | { |
39 | 0 | *(long*)&dst[i] ^= *(long*)&src[i]; |
40 | 0 | } |
41 | 0 | break; |
42 | 0 | case sizeof(int): |
43 | 0 | for (m = n - sizeof(int); i <= m; i += sizeof(int)) |
44 | 0 | { |
45 | 0 | *(int*)&dst[i] ^= *(int*)&src[i]; |
46 | 0 | } |
47 | 0 | break; |
48 | 0 | case sizeof(short): |
49 | 0 | for (m = n - sizeof(short); i <= m; i += sizeof(short)) |
50 | 0 | { |
51 | 0 | *(short*)&dst[i] ^= *(short*)&src[i]; |
52 | 0 | } |
53 | 0 | break; |
54 | 0 | default: |
55 | 0 | break; |
56 | 0 | } |
57 | | /* byte wise XOR of the rest */ |
58 | 0 | for (; i < n; i++) |
59 | 0 | { |
60 | 0 | dst[i] ^= src[i]; |
61 | 0 | } |
62 | 0 | } |
63 | | |
64 | | #ifndef HAVE_EXPLICIT_BZERO |
65 | | /** |
66 | | * Described in header. |
67 | | */ |
68 | | void memwipe_noinline(void *ptr, size_t n) |
69 | | { |
70 | | memwipe_inline(ptr, n); |
71 | | } |
72 | | #endif /* HAVE_EXPLICIT_BZERO */ |
73 | | |
74 | | /** |
75 | | * Described in header. |
76 | | */ |
77 | | bool memeq_const(const void *x, const void *y, size_t len) |
78 | 32 | { |
79 | 32 | const u_char *a, *b; |
80 | 32 | u_int bad = 0; |
81 | 32 | size_t i; |
82 | | |
83 | 32 | a = (const u_char*)x; |
84 | 32 | b = (const u_char*)y; |
85 | | |
86 | 8.82k | for (i = 0; i < len; i++) |
87 | 8.79k | { |
88 | 8.79k | bad |= a[i] != b[i]; |
89 | 8.79k | } |
90 | 32 | return !bad; |
91 | 32 | } |
92 | | |
93 | | /** |
94 | | * Described in header. |
95 | | */ |
96 | | void *memstr(const void *haystack, const char *needle, size_t n) |
97 | 0 | { |
98 | 0 | const u_char *pos = haystack; |
99 | 0 | size_t l; |
100 | |
|
101 | 0 | if (!haystack || !needle || (l = strlen(needle)) == 0) |
102 | 0 | { |
103 | 0 | return NULL; |
104 | 0 | } |
105 | 0 | for (; n >= l; ++pos, --n) |
106 | 0 | { |
107 | 0 | if (memeq(pos, needle, l)) |
108 | 0 | { |
109 | 0 | return (void*)pos; |
110 | 0 | } |
111 | 0 | } |
112 | 0 | return NULL; |
113 | 0 | } |
114 | | |
115 | | /** |
116 | | * Described in header. |
117 | | */ |
118 | | void *utils_memrchr(const void *s, int c, size_t n) |
119 | 0 | { |
120 | 0 | const u_char *pos; |
121 | |
|
122 | 0 | if (!s || !n) |
123 | 0 | { |
124 | 0 | return NULL; |
125 | 0 | } |
126 | | |
127 | 0 | for (pos = s + n - 1; pos >= (u_char*)s; pos--) |
128 | 0 | { |
129 | 0 | if (*pos == (u_char)c) |
130 | 0 | { |
131 | 0 | return (void*)pos; |
132 | 0 | } |
133 | 0 | } |
134 | 0 | return NULL; |
135 | 0 | } |
136 | | |
137 | | #ifdef HAVE_FMEMOPEN_FALLBACK |
138 | | |
139 | | static int fmemread(chunk_t *cookie, char *buf, int size) |
140 | | { |
141 | | int len; |
142 | | |
143 | | len = min(size, cookie->len); |
144 | | memcpy(buf, cookie->ptr, len); |
145 | | *cookie = chunk_skip(*cookie, len); |
146 | | |
147 | | return len; |
148 | | } |
149 | | |
150 | | static int fmemwrite(chunk_t *cookie, const char *buf, int size) |
151 | | { |
152 | | int len; |
153 | | |
154 | | len = min(size, cookie->len); |
155 | | memcpy(cookie->ptr, buf, len); |
156 | | *cookie = chunk_skip(*cookie, len); |
157 | | |
158 | | return len; |
159 | | } |
160 | | |
161 | | static int fmemclose(void *cookie) |
162 | | { |
163 | | free(cookie); |
164 | | return 0; |
165 | | } |
166 | | |
167 | | FILE *fmemopen(void *buf, size_t size, const char *mode) |
168 | | { |
169 | | chunk_t *cookie; |
170 | | |
171 | | INIT(cookie, |
172 | | .ptr = buf, |
173 | | .len = size, |
174 | | ); |
175 | | |
176 | | return funopen(cookie, (void*)fmemread, (void*)fmemwrite, NULL, fmemclose); |
177 | | } |
178 | | |
179 | | #endif /* FMEMOPEN fallback*/ |
180 | | |
181 | | /** |
182 | | * Number of bytes per line to dump raw data |
183 | | */ |
184 | 0 | #define BYTES_PER_LINE 16 |
185 | | |
186 | | static char hexdig_upper[] = "0123456789ABCDEF"; |
187 | | |
188 | | /** |
189 | | * Described in header. |
190 | | */ |
191 | | int mem_printf_hook(printf_hook_data_t *data, |
192 | | printf_hook_spec_t *spec, const void *const *args) |
193 | 0 | { |
194 | 0 | char *bytes = *((void**)(args[0])); |
195 | 0 | u_int len = *((int*)(args[1])); |
196 | |
|
197 | 0 | char buffer[BYTES_PER_LINE * 3]; |
198 | 0 | char ascii_buffer[BYTES_PER_LINE + 1]; |
199 | 0 | char *buffer_pos = buffer; |
200 | 0 | char *bytes_pos = bytes; |
201 | 0 | char *bytes_roof = bytes + len; |
202 | 0 | int line_start = 0; |
203 | 0 | int i = 0; |
204 | 0 | int written = 0; |
205 | |
|
206 | 0 | written += print_in_hook(data, "=> %u bytes @ %p", len, bytes); |
207 | |
|
208 | 0 | while (bytes_pos < bytes_roof) |
209 | 0 | { |
210 | 0 | *buffer_pos++ = hexdig_upper[(*bytes_pos >> 4) & 0xF]; |
211 | 0 | *buffer_pos++ = hexdig_upper[ *bytes_pos & 0xF]; |
212 | |
|
213 | 0 | ascii_buffer[i++] = |
214 | 0 | (*bytes_pos > 31 && *bytes_pos < 127) ? *bytes_pos : '.'; |
215 | |
|
216 | 0 | if (++bytes_pos == bytes_roof || i == BYTES_PER_LINE) |
217 | 0 | { |
218 | 0 | int padding = 3 * (BYTES_PER_LINE - i); |
219 | |
|
220 | 0 | while (padding--) |
221 | 0 | { |
222 | 0 | *buffer_pos++ = ' '; |
223 | 0 | } |
224 | 0 | *buffer_pos++ = '\0'; |
225 | 0 | ascii_buffer[i] = '\0'; |
226 | |
|
227 | 0 | written += print_in_hook(data, "\n%4d: %s %s", |
228 | 0 | line_start, buffer, ascii_buffer); |
229 | |
|
230 | 0 | buffer_pos = buffer; |
231 | 0 | line_start += BYTES_PER_LINE; |
232 | 0 | i = 0; |
233 | 0 | } |
234 | 0 | else |
235 | 0 | { |
236 | 0 | *buffer_pos++ = ' '; |
237 | 0 | } |
238 | 0 | } |
239 | 0 | return written; |
240 | 0 | } |