1/* BEGIN_HEADER */
2#include "mbedtls/memory_buffer_alloc.h"
3#define TEST_SUITE_MEMORY_BUFFER_ALLOC
4
5/* END_HEADER */
6
7/* BEGIN_DEPENDENCIES
8 * depends_on:MBEDTLS_MEMORY_BUFFER_ALLOC_C
9 * END_DEPENDENCIES
10 */
11
12/* BEGIN_SUITE_HELPERS */
13static int check_pointer(void *p)
14{
15    if (p == NULL) {
16        return -1;
17    }
18
19    if ((size_t) p % MBEDTLS_MEMORY_ALIGN_MULTIPLE != 0) {
20        return -1;
21    }
22
23    return 0;
24}
25/* END_SUITE_HELPERS */
26
27/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
28void mbedtls_memory_buffer_alloc_self_test()
29{
30    TEST_ASSERT(mbedtls_memory_buffer_alloc_self_test(1) == 0);
31}
32/* END_CASE */
33
34/* BEGIN_CASE */
35void memory_buffer_alloc_free_alloc(int a_bytes, int b_bytes, int c_bytes,
36                                    int d_bytes, int free_a, int free_b,
37                                    int free_c, int free_d, int e_bytes,
38                                    int f_bytes)
39{
40    unsigned char buf[1024];
41    unsigned char *ptr_a = NULL, *ptr_b = NULL, *ptr_c = NULL, *ptr_d = NULL,
42                  *ptr_e = NULL, *ptr_f = NULL;
43
44#if defined(MBEDTLS_MEMORY_DEBUG)
45    size_t reported_blocks;
46    size_t reported_bytes;
47#endif
48    size_t allocated_bytes = 0;
49
50    mbedtls_memory_buffer_alloc_init(buf, sizeof(buf));
51
52    mbedtls_memory_buffer_set_verify(MBEDTLS_MEMORY_VERIFY_ALWAYS);
53
54    if (a_bytes > 0) {
55        ptr_a = mbedtls_calloc(a_bytes, sizeof(char));
56        TEST_ASSERT(check_pointer(ptr_a) == 0);
57
58        allocated_bytes += a_bytes * sizeof(char);
59    }
60
61    if (b_bytes > 0) {
62        ptr_b = mbedtls_calloc(b_bytes, sizeof(char));
63        TEST_ASSERT(check_pointer(ptr_b) == 0);
64
65        allocated_bytes += b_bytes * sizeof(char);
66    }
67
68    if (c_bytes > 0) {
69        ptr_c = mbedtls_calloc(c_bytes, sizeof(char));
70        TEST_ASSERT(check_pointer(ptr_c) == 0);
71
72        allocated_bytes += c_bytes * sizeof(char);
73    }
74
75    if (d_bytes > 0) {
76        ptr_d = mbedtls_calloc(d_bytes, sizeof(char));
77        TEST_ASSERT(check_pointer(ptr_d) == 0);
78
79        allocated_bytes += d_bytes * sizeof(char);
80    }
81
82#if defined(MBEDTLS_MEMORY_DEBUG)
83    mbedtls_memory_buffer_alloc_cur_get(&reported_bytes, &reported_blocks);
84    TEST_ASSERT(reported_bytes == allocated_bytes);
85#endif
86
87    if (free_a) {
88        mbedtls_free(ptr_a);
89        ptr_a = NULL;
90        TEST_ASSERT(mbedtls_memory_buffer_alloc_verify() == 0);
91
92        allocated_bytes -= a_bytes * sizeof(char);
93    }
94
95    if (free_b) {
96        mbedtls_free(ptr_b);
97        ptr_b = NULL;
98        TEST_ASSERT(mbedtls_memory_buffer_alloc_verify() == 0);
99
100        allocated_bytes -= b_bytes * sizeof(char);
101    }
102
103    if (free_c) {
104        mbedtls_free(ptr_c);
105        ptr_c = NULL;
106        TEST_ASSERT(mbedtls_memory_buffer_alloc_verify() == 0);
107
108        allocated_bytes -= c_bytes * sizeof(char);
109    }
110
111    if (free_d) {
112        mbedtls_free(ptr_d);
113        ptr_d = NULL;
114        TEST_ASSERT(mbedtls_memory_buffer_alloc_verify() == 0);
115
116        allocated_bytes -= d_bytes * sizeof(char);
117    }
118
119#if defined(MBEDTLS_MEMORY_DEBUG)
120    mbedtls_memory_buffer_alloc_cur_get(&reported_bytes, &reported_blocks);
121    TEST_ASSERT(reported_bytes == allocated_bytes);
122#endif
123
124    if (e_bytes > 0) {
125        ptr_e = mbedtls_calloc(e_bytes, sizeof(char));
126        TEST_ASSERT(check_pointer(ptr_e) == 0);
127    }
128
129    if (f_bytes > 0) {
130        ptr_f = mbedtls_calloc(f_bytes, sizeof(char));
131        TEST_ASSERT(check_pointer(ptr_f) == 0);
132    }
133
134    /* Once blocks are reallocated, the block allocated to the memory request
135     * may be bigger than the request itself, which is indicated by the reported
136     * bytes, and makes it hard to know what the reported size will be, so
137     * we don't check the size after blocks have been reallocated. */
138
139    if (ptr_a != NULL) {
140        mbedtls_free(ptr_a);
141        ptr_a = NULL;
142        TEST_ASSERT(mbedtls_memory_buffer_alloc_verify() == 0);
143    }
144
145    if (ptr_b != NULL) {
146        mbedtls_free(ptr_b);
147        ptr_b = NULL;
148        TEST_ASSERT(mbedtls_memory_buffer_alloc_verify() == 0);
149    }
150
151    if (ptr_c != NULL) {
152        mbedtls_free(ptr_c);
153        ptr_c = NULL;
154        TEST_ASSERT(mbedtls_memory_buffer_alloc_verify() == 0);
155    }
156
157    if (ptr_d != NULL) {
158        mbedtls_free(ptr_d);
159        ptr_d = NULL;
160        TEST_ASSERT(mbedtls_memory_buffer_alloc_verify() == 0);
161    }
162
163    if (ptr_e != NULL) {
164        mbedtls_free(ptr_e);
165        ptr_e = NULL;
166        TEST_ASSERT(mbedtls_memory_buffer_alloc_verify() == 0);
167    }
168
169    if (ptr_f != NULL) {
170        mbedtls_free(ptr_f);
171        ptr_f = NULL;
172    }
173
174#if defined(MBEDTLS_MEMORY_DEBUG)
175    mbedtls_memory_buffer_alloc_cur_get(&reported_bytes, &reported_blocks);
176    TEST_ASSERT(reported_bytes == 0);
177#endif
178
179    TEST_ASSERT(mbedtls_memory_buffer_alloc_verify() == 0);
180
181exit:
182    mbedtls_memory_buffer_alloc_free();
183}
184/* END_CASE */
185
186/* BEGIN_CASE */
187void memory_buffer_alloc_oom_test()
188{
189    unsigned char buf[1024];
190    unsigned char *ptr_a = NULL, *ptr_b = NULL, *ptr_c = NULL;
191#if defined(MBEDTLS_MEMORY_DEBUG)
192    size_t reported_blocks, reported_bytes;
193#endif
194
195    (void) ptr_c;
196
197    mbedtls_memory_buffer_alloc_init(buf, sizeof(buf));
198
199    mbedtls_memory_buffer_set_verify(MBEDTLS_MEMORY_VERIFY_ALWAYS);
200
201    ptr_a = mbedtls_calloc(432, sizeof(char));
202    TEST_ASSERT(check_pointer(ptr_a) == 0);
203
204    ptr_b = mbedtls_calloc(432, sizeof(char));
205    TEST_ASSERT(check_pointer(ptr_b) == 0);
206
207    ptr_c = mbedtls_calloc(431, sizeof(char));
208    TEST_ASSERT(ptr_c == NULL);
209
210#if defined(MBEDTLS_MEMORY_DEBUG)
211    mbedtls_memory_buffer_alloc_cur_get(&reported_bytes, &reported_blocks);
212    TEST_ASSERT(reported_bytes >= 864 && reported_bytes <= sizeof(buf));
213#endif
214
215    mbedtls_free(ptr_a);
216    ptr_a = NULL;
217    TEST_ASSERT(mbedtls_memory_buffer_alloc_verify() == 0);
218
219    mbedtls_free(ptr_b);
220    ptr_b = NULL;
221    TEST_ASSERT(mbedtls_memory_buffer_alloc_verify() == 0);
222
223#if defined(MBEDTLS_MEMORY_DEBUG)
224    mbedtls_memory_buffer_alloc_cur_get(&reported_bytes, &reported_blocks);
225    TEST_ASSERT(reported_bytes == 0);
226#endif
227
228    TEST_ASSERT(mbedtls_memory_buffer_alloc_verify() == 0);
229
230exit:
231    mbedtls_memory_buffer_alloc_free();
232}
233/* END_CASE */
234
235/* BEGIN_CASE */
236void memory_buffer_heap_too_small()
237{
238    unsigned char buf[1];
239
240    mbedtls_memory_buffer_alloc_init(buf, sizeof(buf));
241    /* With MBEDTLS_MEMORY_DEBUG enabled, this prints a message
242     * "FATAL: verification of first header failed".
243     */
244    TEST_ASSERT(mbedtls_memory_buffer_alloc_verify() != 0);
245}
246/* END_CASE */
247
248/* BEGIN_CASE */
249void memory_buffer_underalloc()
250{
251    unsigned char buf[100];
252    size_t i;
253
254    mbedtls_memory_buffer_alloc_init(buf, sizeof(buf));
255    for (i = 1; i < MBEDTLS_MEMORY_ALIGN_MULTIPLE; i++) {
256        TEST_ASSERT(mbedtls_calloc(1,
257                                   (size_t) -(MBEDTLS_MEMORY_ALIGN_MULTIPLE - i)) == NULL);
258        TEST_ASSERT(mbedtls_memory_buffer_alloc_verify() == 0);
259    }
260
261exit:
262    mbedtls_memory_buffer_alloc_free();
263}
264/* END_CASE */
265