Coverage Report

Created: 2024-02-29 06:05

/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
}