blob: c188b1d82a62760fa934b1852a549617284ccf2d [file] [log] [blame]
Paul Bakker6e339b52013-07-03 13:37:05 +02001/*
2 * Buffer-based memory allocator
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker6e339b52013-07-03 13:37:05 +020018 */
19
Gilles Peskinedb09ef62020-06-03 01:43:33 +020020#include "common.h"
Paul Bakker6e339b52013-07-03 13:37:05 +020021
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020022#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020023# include "mbedtls/memory_buffer_alloc.h"
Paul Bakker6e339b52013-07-03 13:37:05 +020024
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020025/* No need for the header guard as MBEDTLS_MEMORY_BUFFER_ALLOC_C
26 is dependent upon MBEDTLS_PLATFORM_C */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020027# include "mbedtls/platform.h"
28# include "mbedtls/platform_util.h"
Rich Evansd08a6052015-02-12 12:17:10 +000029
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020030# include <string.h>
Paul Bakker6e339b52013-07-03 13:37:05 +020031
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020032# if defined(MBEDTLS_MEMORY_BACKTRACE)
33# include <execinfo.h>
34# endif
Paul Bakker6e339b52013-07-03 13:37:05 +020035
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020036# if defined(MBEDTLS_THREADING_C)
37# include "mbedtls/threading.h"
38# endif
Paul Bakker1337aff2013-09-29 14:45:34 +020039
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020040# define MAGIC1 0xFF00AA55
41# define MAGIC2 0xEE119966
42# define MAX_BT 20
Paul Bakker6e339b52013-07-03 13:37:05 +020043
44typedef struct _memory_header memory_header;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020045struct _memory_header {
46 size_t magic1;
47 size_t size;
48 size_t alloc;
49 memory_header *prev;
50 memory_header *next;
51 memory_header *prev_free;
52 memory_header *next_free;
53# if defined(MBEDTLS_MEMORY_BACKTRACE)
54 char **trace;
55 size_t trace_count;
56# endif
57 size_t magic2;
Paul Bakker6e339b52013-07-03 13:37:05 +020058};
59
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020060typedef struct {
61 unsigned char *buf;
62 size_t len;
63 memory_header *first;
64 memory_header *first_free;
65 int verify;
66# if defined(MBEDTLS_MEMORY_DEBUG)
67 size_t alloc_count;
68 size_t free_count;
69 size_t total_used;
70 size_t maximum_used;
71 size_t header_count;
72 size_t maximum_header_count;
73# endif
74# if defined(MBEDTLS_THREADING_C)
75 mbedtls_threading_mutex_t mutex;
76# endif
77} buffer_alloc_ctx;
Paul Bakker6e339b52013-07-03 13:37:05 +020078
79static buffer_alloc_ctx heap;
80
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020081# if defined(MBEDTLS_MEMORY_DEBUG)
82static void debug_header(memory_header *hdr)
Paul Bakker6e339b52013-07-03 13:37:05 +020083{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020084# if defined(MBEDTLS_MEMORY_BACKTRACE)
Paul Bakker6e339b52013-07-03 13:37:05 +020085 size_t i;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020086# endif
Paul Bakker6e339b52013-07-03 13:37:05 +020087
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020088 mbedtls_fprintf(stderr,
89 "HDR: PTR(%10zu), PREV(%10zu), NEXT(%10zu), "
90 "ALLOC(%zu), SIZE(%10zu)\n",
91 (size_t)hdr, (size_t)hdr->prev, (size_t)hdr->next,
92 hdr->alloc, hdr->size);
93 mbedtls_fprintf(stderr, " FPREV(%10zu), FNEXT(%10zu)\n",
94 (size_t)hdr->prev_free, (size_t)hdr->next_free);
Paul Bakker6e339b52013-07-03 13:37:05 +020095
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020096# if defined(MBEDTLS_MEMORY_BACKTRACE)
97 mbedtls_fprintf(stderr, "TRACE: \n");
98 for (i = 0; i < hdr->trace_count; i++)
99 mbedtls_fprintf(stderr, "%s\n", hdr->trace[i]);
100 mbedtls_fprintf(stderr, "\n");
101# endif
Paul Bakker6e339b52013-07-03 13:37:05 +0200102}
103
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200104static void debug_chain(void)
Paul Bakker6e339b52013-07-03 13:37:05 +0200105{
106 memory_header *cur = heap.first;
107
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200108 mbedtls_fprintf(stderr, "\nBlock list\n");
109 while (cur != NULL) {
110 debug_header(cur);
Paul Bakker6e339b52013-07-03 13:37:05 +0200111 cur = cur->next;
112 }
Paul Bakker1ef120f2013-07-03 17:20:39 +0200113
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200114 mbedtls_fprintf(stderr, "Free list\n");
Paul Bakker1ef120f2013-07-03 17:20:39 +0200115 cur = heap.first_free;
116
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200117 while (cur != NULL) {
118 debug_header(cur);
Paul Bakker1ef120f2013-07-03 17:20:39 +0200119 cur = cur->next_free;
120 }
Paul Bakker6e339b52013-07-03 13:37:05 +0200121}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200122# endif /* MBEDTLS_MEMORY_DEBUG */
Paul Bakker6e339b52013-07-03 13:37:05 +0200123
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200124static int verify_header(memory_header *hdr)
Paul Bakker6e339b52013-07-03 13:37:05 +0200125{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200126 if (hdr->magic1 != MAGIC1) {
127# if defined(MBEDTLS_MEMORY_DEBUG)
128 mbedtls_fprintf(stderr, "FATAL: MAGIC1 mismatch\n");
129# endif
130 return 1;
Paul Bakker6e339b52013-07-03 13:37:05 +0200131 }
132
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200133 if (hdr->magic2 != MAGIC2) {
134# if defined(MBEDTLS_MEMORY_DEBUG)
135 mbedtls_fprintf(stderr, "FATAL: MAGIC2 mismatch\n");
136# endif
137 return 1;
Paul Bakker6e339b52013-07-03 13:37:05 +0200138 }
139
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200140 if (hdr->alloc > 1) {
141# if defined(MBEDTLS_MEMORY_DEBUG)
142 mbedtls_fprintf(stderr, "FATAL: alloc has illegal value\n");
143# endif
144 return 1;
Paul Bakker6e339b52013-07-03 13:37:05 +0200145 }
146
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200147 if (hdr->prev != NULL && hdr->prev == hdr->next) {
148# if defined(MBEDTLS_MEMORY_DEBUG)
149 mbedtls_fprintf(stderr, "FATAL: prev == next\n");
150# endif
151 return 1;
Paul Bakker1ef120f2013-07-03 17:20:39 +0200152 }
153
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200154 if (hdr->prev_free != NULL && hdr->prev_free == hdr->next_free) {
155# if defined(MBEDTLS_MEMORY_DEBUG)
156 mbedtls_fprintf(stderr, "FATAL: prev_free == next_free\n");
157# endif
158 return 1;
Paul Bakker1ef120f2013-07-03 17:20:39 +0200159 }
160
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200161 return 0;
Paul Bakker6e339b52013-07-03 13:37:05 +0200162}
163
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200164static int verify_chain(void)
Paul Bakker6e339b52013-07-03 13:37:05 +0200165{
Andres AG9cf1f962017-01-30 14:34:25 +0000166 memory_header *prv = heap.first, *cur;
Paul Bakker6e339b52013-07-03 13:37:05 +0200167
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200168 if (prv == NULL || verify_header(prv) != 0) {
169# if defined(MBEDTLS_MEMORY_DEBUG)
170 mbedtls_fprintf(stderr, "FATAL: verification of first header "
171 "failed\n");
172# endif
173 return 1;
Paul Bakker6e339b52013-07-03 13:37:05 +0200174 }
175
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200176 if (heap.first->prev != NULL) {
177# if defined(MBEDTLS_MEMORY_DEBUG)
178 mbedtls_fprintf(stderr, "FATAL: verification failed: "
179 "first->prev != NULL\n");
180# endif
181 return 1;
Paul Bakker6e339b52013-07-03 13:37:05 +0200182 }
183
Andres AG9cf1f962017-01-30 14:34:25 +0000184 cur = heap.first->next;
185
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200186 while (cur != NULL) {
187 if (verify_header(cur) != 0) {
188# if defined(MBEDTLS_MEMORY_DEBUG)
189 mbedtls_fprintf(stderr, "FATAL: verification of header "
190 "failed\n");
191# endif
192 return 1;
Paul Bakker6e339b52013-07-03 13:37:05 +0200193 }
194
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200195 if (cur->prev != prv) {
196# if defined(MBEDTLS_MEMORY_DEBUG)
197 mbedtls_fprintf(stderr, "FATAL: verification failed: "
198 "cur->prev != prv\n");
199# endif
200 return 1;
Paul Bakker6e339b52013-07-03 13:37:05 +0200201 }
202
203 prv = cur;
204 cur = cur->next;
205 }
206
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200207 return 0;
Paul Bakker6e339b52013-07-03 13:37:05 +0200208}
209
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200210static void *buffer_alloc_calloc(size_t n, size_t size)
Paul Bakker6e339b52013-07-03 13:37:05 +0200211{
Paul Bakker1ef120f2013-07-03 17:20:39 +0200212 memory_header *new, *cur = heap.first_free;
Paul Bakker6e339b52013-07-03 13:37:05 +0200213 unsigned char *p;
Manuel Pégourié-Gonnard200e7312015-05-26 17:42:13 +0200214 void *ret;
215 size_t original_len, len;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200216# if defined(MBEDTLS_MEMORY_BACKTRACE)
Paul Bakker6e339b52013-07-03 13:37:05 +0200217 void *trace_buffer[MAX_BT];
218 size_t trace_cnt;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200219# endif
Paul Bakker6e339b52013-07-03 13:37:05 +0200220
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200221 if (heap.buf == NULL || heap.first == NULL)
222 return NULL;
Paul Bakker6e339b52013-07-03 13:37:05 +0200223
Manuel Pégourié-Gonnard200e7312015-05-26 17:42:13 +0200224 original_len = len = n * size;
225
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200226 if (n == 0 || size == 0 || len / n != size)
227 return NULL;
228 else if (len > (size_t)-MBEDTLS_MEMORY_ALIGN_MULTIPLE)
229 return NULL;
Manuel Pégourié-Gonnard200e7312015-05-26 17:42:13 +0200230
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200231 if (len % MBEDTLS_MEMORY_ALIGN_MULTIPLE) {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200232 len -= len % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
233 len += MBEDTLS_MEMORY_ALIGN_MULTIPLE;
Paul Bakker6e339b52013-07-03 13:37:05 +0200234 }
235
236 // Find block that fits
237 //
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200238 while (cur != NULL) {
239 if (cur->size >= len)
Paul Bakker6e339b52013-07-03 13:37:05 +0200240 break;
241
Paul Bakker1ef120f2013-07-03 17:20:39 +0200242 cur = cur->next_free;
Paul Bakker6e339b52013-07-03 13:37:05 +0200243 }
244
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200245 if (cur == NULL)
246 return NULL;
Paul Bakker6e339b52013-07-03 13:37:05 +0200247
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200248 if (cur->alloc != 0) {
249# if defined(MBEDTLS_MEMORY_DEBUG)
250 mbedtls_fprintf(stderr, "FATAL: block in free_list but allocated "
251 "data\n");
252# endif
253 mbedtls_exit(1);
Paul Bakker1ef120f2013-07-03 17:20:39 +0200254 }
255
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200256# if defined(MBEDTLS_MEMORY_DEBUG)
Manuel Pégourié-Gonnard6c967b92015-05-27 20:18:39 +0200257 heap.alloc_count++;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200258# endif
Paul Bakker891998e2013-07-03 14:45:05 +0200259
Paul Bakker6e339b52013-07-03 13:37:05 +0200260 // Found location, split block if > memory_header + 4 room left
261 //
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200262 if (cur->size - len <
263 sizeof(memory_header) + MBEDTLS_MEMORY_ALIGN_MULTIPLE) {
Paul Bakker6e339b52013-07-03 13:37:05 +0200264 cur->alloc = 1;
265
Paul Bakker1ef120f2013-07-03 17:20:39 +0200266 // Remove from free_list
267 //
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200268 if (cur->prev_free != NULL)
Paul Bakker1ef120f2013-07-03 17:20:39 +0200269 cur->prev_free->next_free = cur->next_free;
270 else
271 heap.first_free = cur->next_free;
272
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200273 if (cur->next_free != NULL)
Paul Bakker1ef120f2013-07-03 17:20:39 +0200274 cur->next_free->prev_free = cur->prev_free;
275
276 cur->prev_free = NULL;
277 cur->next_free = NULL;
278
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200279# if defined(MBEDTLS_MEMORY_DEBUG)
Paul Bakker891998e2013-07-03 14:45:05 +0200280 heap.total_used += cur->size;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200281 if (heap.total_used > heap.maximum_used)
Paul Bakker891998e2013-07-03 14:45:05 +0200282 heap.maximum_used = heap.total_used;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200283# endif
284# if defined(MBEDTLS_MEMORY_BACKTRACE)
285 trace_cnt = backtrace(trace_buffer, MAX_BT);
286 cur->trace = backtrace_symbols(trace_buffer, trace_cnt);
Paul Bakker6e339b52013-07-03 13:37:05 +0200287 cur->trace_count = trace_cnt;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200288# endif
Paul Bakker6e339b52013-07-03 13:37:05 +0200289
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200290 if ((heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC) && verify_chain() != 0)
291 mbedtls_exit(1);
Paul Bakker6e339b52013-07-03 13:37:05 +0200292
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200293 ret = (unsigned char *)cur + sizeof(memory_header);
294 memset(ret, 0, original_len);
Manuel Pégourié-Gonnard200e7312015-05-26 17:42:13 +0200295
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200296 return ret;
Paul Bakker6e339b52013-07-03 13:37:05 +0200297 }
298
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200299 p = ((unsigned char *)cur) + sizeof(memory_header) + len;
300 new = (memory_header *)p;
Paul Bakker6e339b52013-07-03 13:37:05 +0200301
302 new->size = cur->size - len - sizeof(memory_header);
303 new->alloc = 0;
304 new->prev = cur;
305 new->next = cur->next;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200306# if defined(MBEDTLS_MEMORY_BACKTRACE)
Paul Bakker6e339b52013-07-03 13:37:05 +0200307 new->trace = NULL;
308 new->trace_count = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200309# endif
Paul Bakker6e339b52013-07-03 13:37:05 +0200310 new->magic1 = MAGIC1;
311 new->magic2 = MAGIC2;
312
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200313 if (new->next != NULL)
Paul Bakker6e339b52013-07-03 13:37:05 +0200314 new->next->prev = new;
315
Paul Bakker1ef120f2013-07-03 17:20:39 +0200316 // Replace cur with new in free_list
317 //
318 new->prev_free = cur->prev_free;
319 new->next_free = cur->next_free;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200320 if (new->prev_free != NULL)
Paul Bakker1ef120f2013-07-03 17:20:39 +0200321 new->prev_free->next_free = new;
322 else
323 heap.first_free = new;
324
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200325 if (new->next_free != NULL)
Paul Bakker1ef120f2013-07-03 17:20:39 +0200326 new->next_free->prev_free = new;
327
Paul Bakker6e339b52013-07-03 13:37:05 +0200328 cur->alloc = 1;
329 cur->size = len;
330 cur->next = new;
Paul Bakker1ef120f2013-07-03 17:20:39 +0200331 cur->prev_free = NULL;
332 cur->next_free = NULL;
Paul Bakker6e339b52013-07-03 13:37:05 +0200333
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200334# if defined(MBEDTLS_MEMORY_DEBUG)
Paul Bakker891998e2013-07-03 14:45:05 +0200335 heap.header_count++;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200336 if (heap.header_count > heap.maximum_header_count)
Manuel Pégourié-Gonnard70896a02013-12-30 18:06:41 +0100337 heap.maximum_header_count = heap.header_count;
Paul Bakker891998e2013-07-03 14:45:05 +0200338 heap.total_used += cur->size;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200339 if (heap.total_used > heap.maximum_used)
Paul Bakker891998e2013-07-03 14:45:05 +0200340 heap.maximum_used = heap.total_used;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200341# endif
342# if defined(MBEDTLS_MEMORY_BACKTRACE)
343 trace_cnt = backtrace(trace_buffer, MAX_BT);
344 cur->trace = backtrace_symbols(trace_buffer, trace_cnt);
Paul Bakker6e339b52013-07-03 13:37:05 +0200345 cur->trace_count = trace_cnt;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200346# endif
Paul Bakker6e339b52013-07-03 13:37:05 +0200347
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200348 if ((heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC) && verify_chain() != 0)
349 mbedtls_exit(1);
Paul Bakker6e339b52013-07-03 13:37:05 +0200350
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200351 ret = (unsigned char *)cur + sizeof(memory_header);
352 memset(ret, 0, original_len);
Manuel Pégourié-Gonnard200e7312015-05-26 17:42:13 +0200353
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200354 return ret;
Paul Bakker6e339b52013-07-03 13:37:05 +0200355}
356
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200357static void buffer_alloc_free(void *ptr)
Paul Bakker6e339b52013-07-03 13:37:05 +0200358{
Paul Bakker1ef120f2013-07-03 17:20:39 +0200359 memory_header *hdr, *old = NULL;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200360 unsigned char *p = (unsigned char *)ptr;
Paul Bakker6e339b52013-07-03 13:37:05 +0200361
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200362 if (ptr == NULL || heap.buf == NULL || heap.first == NULL)
Paul Bakker6e339b52013-07-03 13:37:05 +0200363 return;
364
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200365 if (p < heap.buf || p >= heap.buf + heap.len) {
366# if defined(MBEDTLS_MEMORY_DEBUG)
367 mbedtls_fprintf(stderr, "FATAL: mbedtls_free() outside of managed "
368 "space\n");
369# endif
370 mbedtls_exit(1);
Paul Bakker6e339b52013-07-03 13:37:05 +0200371 }
372
373 p -= sizeof(memory_header);
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200374 hdr = (memory_header *)p;
Paul Bakker6e339b52013-07-03 13:37:05 +0200375
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200376 if (verify_header(hdr) != 0)
377 mbedtls_exit(1);
Paul Bakker6e339b52013-07-03 13:37:05 +0200378
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200379 if (hdr->alloc != 1) {
380# if defined(MBEDTLS_MEMORY_DEBUG)
381 mbedtls_fprintf(stderr, "FATAL: mbedtls_free() on unallocated "
382 "data\n");
383# endif
384 mbedtls_exit(1);
Paul Bakker6e339b52013-07-03 13:37:05 +0200385 }
386
387 hdr->alloc = 0;
388
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200389# if defined(MBEDTLS_MEMORY_DEBUG)
Paul Bakker891998e2013-07-03 14:45:05 +0200390 heap.free_count++;
391 heap.total_used -= hdr->size;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200392# endif
Paul Bakker891998e2013-07-03 14:45:05 +0200393
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200394# if defined(MBEDTLS_MEMORY_BACKTRACE)
395 free(hdr->trace);
SimonB42256112016-05-02 01:05:22 +0100396 hdr->trace = NULL;
397 hdr->trace_count = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200398# endif
SimonB42256112016-05-02 01:05:22 +0100399
Paul Bakker6e339b52013-07-03 13:37:05 +0200400 // Regroup with block before
401 //
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200402 if (hdr->prev != NULL && hdr->prev->alloc == 0) {
403# if defined(MBEDTLS_MEMORY_DEBUG)
Paul Bakker891998e2013-07-03 14:45:05 +0200404 heap.header_count--;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200405# endif
Paul Bakker6e339b52013-07-03 13:37:05 +0200406 hdr->prev->size += sizeof(memory_header) + hdr->size;
407 hdr->prev->next = hdr->next;
408 old = hdr;
409 hdr = hdr->prev;
410
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200411 if (hdr->next != NULL)
Paul Bakker6e339b52013-07-03 13:37:05 +0200412 hdr->next->prev = hdr;
413
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200414 memset(old, 0, sizeof(memory_header));
Paul Bakker6e339b52013-07-03 13:37:05 +0200415 }
416
417 // Regroup with block after
418 //
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200419 if (hdr->next != NULL && hdr->next->alloc == 0) {
420# if defined(MBEDTLS_MEMORY_DEBUG)
Paul Bakker891998e2013-07-03 14:45:05 +0200421 heap.header_count--;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200422# endif
Paul Bakker6e339b52013-07-03 13:37:05 +0200423 hdr->size += sizeof(memory_header) + hdr->next->size;
424 old = hdr->next;
425 hdr->next = hdr->next->next;
426
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200427 if (hdr->prev_free != NULL || hdr->next_free != NULL) {
428 if (hdr->prev_free != NULL)
Paul Bakker1ef120f2013-07-03 17:20:39 +0200429 hdr->prev_free->next_free = hdr->next_free;
430 else
431 heap.first_free = hdr->next_free;
432
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200433 if (hdr->next_free != NULL)
Paul Bakker1ef120f2013-07-03 17:20:39 +0200434 hdr->next_free->prev_free = hdr->prev_free;
435 }
436
437 hdr->prev_free = old->prev_free;
438 hdr->next_free = old->next_free;
439
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200440 if (hdr->prev_free != NULL)
Paul Bakker1ef120f2013-07-03 17:20:39 +0200441 hdr->prev_free->next_free = hdr;
442 else
443 heap.first_free = hdr;
444
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200445 if (hdr->next_free != NULL)
Paul Bakker1ef120f2013-07-03 17:20:39 +0200446 hdr->next_free->prev_free = hdr;
447
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200448 if (hdr->next != NULL)
Paul Bakker6e339b52013-07-03 13:37:05 +0200449 hdr->next->prev = hdr;
450
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200451 memset(old, 0, sizeof(memory_header));
Paul Bakker6e339b52013-07-03 13:37:05 +0200452 }
453
Paul Bakker1ef120f2013-07-03 17:20:39 +0200454 // Prepend to free_list if we have not merged
455 // (Does not have to stay in same order as prev / next list)
456 //
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200457 if (old == NULL) {
Paul Bakker1ef120f2013-07-03 17:20:39 +0200458 hdr->next_free = heap.first_free;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200459 if (heap.first_free != NULL)
Manuel Pégourié-Gonnard547ff662014-11-26 15:42:16 +0100460 heap.first_free->prev_free = hdr;
Paul Bakker1ef120f2013-07-03 17:20:39 +0200461 heap.first_free = hdr;
462 }
463
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200464 if ((heap.verify & MBEDTLS_MEMORY_VERIFY_FREE) && verify_chain() != 0)
465 mbedtls_exit(1);
Paul Bakker6e339b52013-07-03 13:37:05 +0200466}
467
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200468void mbedtls_memory_buffer_set_verify(int verify)
Paul Bakkerbf796ac2013-09-28 11:06:38 +0200469{
470 heap.verify = verify;
471}
472
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200473int mbedtls_memory_buffer_alloc_verify(void)
Paul Bakker6e339b52013-07-03 13:37:05 +0200474{
475 return verify_chain();
476}
477
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200478# if defined(MBEDTLS_MEMORY_DEBUG)
479void mbedtls_memory_buffer_alloc_status(void)
Paul Bakker6e339b52013-07-03 13:37:05 +0200480{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200481 mbedtls_fprintf(stderr,
482 "Current use: %zu blocks / %zu bytes, max: %zu blocks / "
483 "%zu bytes (total %zu bytes), alloc / free: %zu / %zu\n",
484 heap.header_count, heap.total_used,
485 heap.maximum_header_count, heap.maximum_used,
486 heap.maximum_header_count * sizeof(memory_header) +
487 heap.maximum_used,
488 heap.alloc_count, heap.free_count);
Paul Bakker891998e2013-07-03 14:45:05 +0200489
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200490 if (heap.first->next == NULL) {
491 mbedtls_fprintf(stderr, "All memory de-allocated in stack buffer\n");
492 } else {
493 mbedtls_fprintf(stderr, "Memory currently allocated:\n");
Paul Bakker6e339b52013-07-03 13:37:05 +0200494 debug_chain();
495 }
496}
Manuel Pégourié-Gonnard50da0482014-12-19 12:10:37 +0100497
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200498void mbedtls_memory_buffer_alloc_max_get(size_t *max_used, size_t *max_blocks)
Manuel Pégourié-Gonnard50da0482014-12-19 12:10:37 +0100499{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200500 *max_used = heap.maximum_used;
Manuel Pégourié-Gonnard50da0482014-12-19 12:10:37 +0100501 *max_blocks = heap.maximum_header_count;
502}
503
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200504void mbedtls_memory_buffer_alloc_max_reset(void)
Manuel Pégourié-Gonnard50da0482014-12-19 12:10:37 +0100505{
506 heap.maximum_used = 0;
507 heap.maximum_header_count = 0;
508}
509
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200510void mbedtls_memory_buffer_alloc_cur_get(size_t *cur_used, size_t *cur_blocks)
Manuel Pégourié-Gonnard50da0482014-12-19 12:10:37 +0100511{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200512 *cur_used = heap.total_used;
Manuel Pégourié-Gonnard50da0482014-12-19 12:10:37 +0100513 *cur_blocks = heap.header_count;
514}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200515# endif /* MBEDTLS_MEMORY_DEBUG */
Paul Bakker6e339b52013-07-03 13:37:05 +0200516
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200517# if defined(MBEDTLS_THREADING_C)
518static void *buffer_alloc_calloc_mutexed(size_t n, size_t size)
Paul Bakker1337aff2013-09-29 14:45:34 +0200519{
520 void *buf;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200521 if (mbedtls_mutex_lock(&heap.mutex) != 0)
522 return NULL;
523 buf = buffer_alloc_calloc(n, size);
524 if (mbedtls_mutex_unlock(&heap.mutex))
525 return NULL;
526 return buf;
Paul Bakker1337aff2013-09-29 14:45:34 +0200527}
528
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200529static void buffer_alloc_free_mutexed(void *ptr)
Paul Bakker1337aff2013-09-29 14:45:34 +0200530{
Manuel Pégourié-Gonnardbdd78282015-04-24 14:42:53 +0200531 /* We have to good option here, but corrupting the heap seems
532 * worse than loosing memory. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200533 if (mbedtls_mutex_lock(&heap.mutex))
Manuel Pégourié-Gonnardbdd78282015-04-24 14:42:53 +0200534 return;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200535 buffer_alloc_free(ptr);
536 (void)mbedtls_mutex_unlock(&heap.mutex);
Paul Bakker1337aff2013-09-29 14:45:34 +0200537}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200538# endif /* MBEDTLS_THREADING_C */
Paul Bakker1337aff2013-09-29 14:45:34 +0200539
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200540void mbedtls_memory_buffer_alloc_init(unsigned char *buf, size_t len)
Paul Bakker6e339b52013-07-03 13:37:05 +0200541{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200542 memset(&heap, 0, sizeof(buffer_alloc_ctx));
Paul Bakker6e339b52013-07-03 13:37:05 +0200543
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200544# if defined(MBEDTLS_THREADING_C)
545 mbedtls_mutex_init(&heap.mutex);
546 mbedtls_platform_set_calloc_free(buffer_alloc_calloc_mutexed,
547 buffer_alloc_free_mutexed);
548# else
549 mbedtls_platform_set_calloc_free(buffer_alloc_calloc, buffer_alloc_free);
550# endif
Paul Bakker1337aff2013-09-29 14:45:34 +0200551
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200552 if (len < sizeof(memory_header) + MBEDTLS_MEMORY_ALIGN_MULTIPLE)
Andres AG9cf1f962017-01-30 14:34:25 +0000553 return;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200554 else if ((size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE) {
Manuel Pégourié-Gonnard5dd28ea2014-11-27 13:57:42 +0100555 /* Adjust len first since buf is used in the computation */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200556 len -= MBEDTLS_MEMORY_ALIGN_MULTIPLE -
557 (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
558 buf += MBEDTLS_MEMORY_ALIGN_MULTIPLE -
559 (size_t)buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE;
Manuel Pégourié-Gonnard82a5de72014-05-05 14:05:24 +0200560 }
561
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200562 memset(buf, 0, len);
Andres AG9cf1f962017-01-30 14:34:25 +0000563
Paul Bakker6e339b52013-07-03 13:37:05 +0200564 heap.buf = buf;
565 heap.len = len;
566
Andres AG9cf1f962017-01-30 14:34:25 +0000567 heap.first = (memory_header *)buf;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200568 heap.first->size = len - sizeof(memory_header);
Paul Bakker6e339b52013-07-03 13:37:05 +0200569 heap.first->magic1 = MAGIC1;
570 heap.first->magic2 = MAGIC2;
Paul Bakker1ef120f2013-07-03 17:20:39 +0200571 heap.first_free = heap.first;
Paul Bakker6e339b52013-07-03 13:37:05 +0200572}
573
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200574void mbedtls_memory_buffer_alloc_free(void)
Paul Bakker1337aff2013-09-29 14:45:34 +0200575{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200576# if defined(MBEDTLS_THREADING_C)
577 mbedtls_mutex_free(&heap.mutex);
578# endif
579 mbedtls_platform_zeroize(&heap, sizeof(buffer_alloc_ctx));
Paul Bakker1337aff2013-09-29 14:45:34 +0200580}
581
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200582# if defined(MBEDTLS_SELF_TEST)
583static int check_pointer(void *p)
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100584{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200585 if (p == NULL)
586 return -1;
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100587
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200588 if ((size_t)p % MBEDTLS_MEMORY_ALIGN_MULTIPLE != 0)
589 return -1;
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100590
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200591 return 0;
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100592}
593
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200594static int check_all_free(void)
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100595{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200596 if (
597# if defined(MBEDTLS_MEMORY_DEBUG)
Manuel Pégourié-Gonnard491a3fe2015-02-05 12:08:47 +0100598 heap.total_used != 0 ||
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200599# endif
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100600 heap.first != heap.first_free ||
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200601 (void *)heap.first != (void *)heap.buf) {
602 return -1;
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100603 }
604
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200605 return 0;
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100606}
607
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200608# define TEST_ASSERT(condition) \
609 if (!(condition)) { \
610 if (verbose != 0) \
611 mbedtls_printf("failed\n"); \
612 \
613 ret = 1; \
614 goto cleanup; \
615 }
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100616
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200617int mbedtls_memory_buffer_alloc_self_test(int verbose)
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100618{
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100619 unsigned char buf[1024];
Manuel Pégourié-Gonnard5dd28ea2014-11-27 13:57:42 +0100620 unsigned char *p, *q, *r, *end;
621 int ret = 0;
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100622
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200623 if (verbose != 0)
624 mbedtls_printf(" MBA test #1 (basic alloc-free cycle): ");
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100625
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200626 mbedtls_memory_buffer_alloc_init(buf, sizeof(buf));
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100627
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200628 p = mbedtls_calloc(1, 1);
629 q = mbedtls_calloc(1, 128);
630 r = mbedtls_calloc(1, 16);
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100631
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200632 TEST_ASSERT(check_pointer(p) == 0 && check_pointer(q) == 0 &&
633 check_pointer(r) == 0);
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100634
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200635 mbedtls_free(r);
636 mbedtls_free(q);
637 mbedtls_free(p);
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100638
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200639 TEST_ASSERT(check_all_free() == 0);
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100640
Manuel Pégourié-Gonnard5dd28ea2014-11-27 13:57:42 +0100641 /* Memorize end to compare with the next test */
642 end = heap.buf + heap.len;
643
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200644 mbedtls_memory_buffer_alloc_free();
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100645
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200646 if (verbose != 0)
647 mbedtls_printf("passed\n");
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100648
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200649 if (verbose != 0)
650 mbedtls_printf(" MBA test #2 (buf not aligned): ");
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100651
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200652 mbedtls_memory_buffer_alloc_init(buf + 1, sizeof(buf) - 1);
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100653
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200654 TEST_ASSERT(heap.buf + heap.len == end);
Manuel Pégourié-Gonnard5dd28ea2014-11-27 13:57:42 +0100655
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200656 p = mbedtls_calloc(1, 1);
657 q = mbedtls_calloc(1, 128);
658 r = mbedtls_calloc(1, 16);
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100659
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200660 TEST_ASSERT(check_pointer(p) == 0 && check_pointer(q) == 0 &&
661 check_pointer(r) == 0);
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100662
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200663 mbedtls_free(r);
664 mbedtls_free(q);
665 mbedtls_free(p);
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100666
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200667 TEST_ASSERT(check_all_free() == 0);
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100668
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200669 mbedtls_memory_buffer_alloc_free();
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100670
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200671 if (verbose != 0)
672 mbedtls_printf("passed\n");
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100673
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200674 if (verbose != 0)
675 mbedtls_printf(" MBA test #3 (full): ");
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100676
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200677 mbedtls_memory_buffer_alloc_init(buf, sizeof(buf));
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100678
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200679 p = mbedtls_calloc(1, sizeof(buf) - sizeof(memory_header));
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100680
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200681 TEST_ASSERT(check_pointer(p) == 0);
682 TEST_ASSERT(mbedtls_calloc(1, 1) == NULL);
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100683
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200684 mbedtls_free(p);
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100685
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200686 p = mbedtls_calloc(1, sizeof(buf) - 2 * sizeof(memory_header) - 16);
687 q = mbedtls_calloc(1, 16);
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100688
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200689 TEST_ASSERT(check_pointer(p) == 0 && check_pointer(q) == 0);
690 TEST_ASSERT(mbedtls_calloc(1, 1) == NULL);
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100691
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200692 mbedtls_free(q);
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100693
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200694 TEST_ASSERT(mbedtls_calloc(1, 17) == NULL);
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100695
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200696 mbedtls_free(p);
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100697
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200698 TEST_ASSERT(check_all_free() == 0);
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100699
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200700 mbedtls_memory_buffer_alloc_free();
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100701
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200702 if (verbose != 0)
703 mbedtls_printf("passed\n");
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100704
705cleanup:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200706 mbedtls_memory_buffer_alloc_free();
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100707
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200708 return ret;
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100709}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200710# endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard5ba1d522014-11-27 11:33:55 +0100711
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200712#endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */