1
2 #ifndef __CMPTEST_H__
3 #define __CMPTEST_H__
4
5 #ifdef NDEBUG
6 #/**/undef/**/ NDEBUG
7 #endif
8
9 #include <assert.h>
10 #include <errno.h>
11 #include <limits.h>
12 #include <stdio.h>
13 #include <stdint.h>
14 #include <stdlib.h>
15 #include <string.h>
16
17 #include "sodium.h"
18 #include "quirks.h"
19
20 #ifdef __EMSCRIPTEN__
21 # undef TEST_SRCDIR
22 # define TEST_SRCDIR "/test-data"
23 #endif
24 #ifndef TEST_SRCDIR
25 # define TEST_SRCDIR "."
26 #endif
27
28 #define TEST_NAME_RES TEST_NAME ".res"
29 #define TEST_NAME_OUT TEST_SRCDIR "/" TEST_NAME ".exp"
30
31 #ifdef HAVE_ARC4RANDOM
32 # undef rand
33 # define rand(X) arc4random(X)
34 #endif
35
36 int xmain(void);
37
38 static unsigned char *guard_page;
39
40 #ifdef BENCHMARKS
41
42 # include <sys/time.h>
43
44 # ifndef ITERATIONS
45 # define ITERATIONS 128
46 # endif
47
48 struct {
49 void *pnt;
50 size_t size;
51 } mempool[1024];
52
53 static size_t mempool_idx;
54
mempool_alloc(size_t size)55 static __attribute__((malloc)) void *mempool_alloc(size_t size)
56 {
57 size_t i;
58 if (size >= (size_t) 0x80000000 - (size_t) 0x00000fff) {
59 return NULL;
60 }
61 size = (size + (size_t) 0x00000fff) & ~ (size_t) 0x00000fff;
62 for (i = 0U; i < mempool_idx; i++) {
63 if (mempool[i].size >= (size | (size_t) 0x80000000)) {
64 mempool[i].size &= ~ (size_t) 0x80000000;
65 return mempool[i].pnt;
66 }
67 }
68 if (mempool_idx >= sizeof mempool / sizeof mempool[0]) {
69 return NULL;
70 }
71 mempool[mempool_idx].size = size;
72 return (mempool[mempool_idx++].pnt = (void *) malloc(size));
73 }
74
mempool_free(void * pnt)75 static void mempool_free(void *pnt)
76 {
77 size_t i;
78 for (i = 0U; i < mempool_idx; i++) {
79 if (mempool[i].pnt == pnt) {
80 if ((mempool[i].size & (size_t) 0x80000000) != (size_t) 0x0) {
81 break;
82 }
83 mempool[i].size |= (size_t) 0x80000000;
84 return;
85 }
86 }
87 abort();
88 }
89
mempool_allocarray(size_t count,size_t size)90 static __attribute__((malloc)) void *mempool_allocarray(size_t count, size_t size)
91 {
92 if (count > (size_t) 0U && size >= (size_t) SIZE_MAX / count) {
93 return NULL;
94 }
95 return mempool_alloc(count * size);
96 }
97
mempool_free_all(void)98 static int mempool_free_all(void)
99 {
100 size_t i;
101 int ret = 0;
102
103 for (i = 0U; i < mempool_idx; i++) {
104 if ((mempool[i].size & (size_t) 0x80000000) == (size_t) 0x0) {
105 ret = -1;
106 }
107 free(mempool[i].pnt);
108 mempool[i].pnt = NULL;
109 }
110 mempool_idx = (size_t) 0U;
111
112 return ret;
113 }
114
115 #define sodium_malloc(X) mempool_alloc(X)
116 #define sodium_free(X) mempool_free(X)
117 #define sodium_allocarray(X, Y) mempool_allocarray((X), (Y))
118
now(void)119 static unsigned long long now(void)
120 {
121 struct timeval tp;
122 unsigned long long now;
123
124 if (gettimeofday(&tp, NULL) != 0) {
125 abort();
126 }
127 now = ((unsigned long long) tp.tv_sec * 1000000ULL) +
128 (unsigned long long) tp.tv_usec;
129
130 return now;
131 }
132
main(void)133 int main(void)
134 {
135 unsigned long long ts_start;
136 unsigned long long ts_end;
137 unsigned int i;
138
139 if (sodium_init() != 0) {
140 return 99;
141 }
142
143 #ifndef __EMSCRIPTEN__
144 randombytes_set_implementation(&randombytes_salsa20_implementation);
145 #endif
146 ts_start = now();
147 for (i = 0; i < ITERATIONS; i++) {
148 if (xmain() != 0) {
149 abort();
150 }
151 }
152 ts_end = now();
153 printf("%llu\n", 1000000ULL * (ts_end - ts_start) / ITERATIONS);
154 if (mempool_free_all() != 0) {
155 fprintf(stderr, "** memory leaks detected **\n");
156 return 99;
157 }
158 return 0;
159 }
160
161 #undef printf
162 #define printf(...) do { } while(0)
163
164 #elif !defined(BROWSER_TESTS)
165
166 static FILE *fp_res;
167
main(void)168 int main(void)
169 {
170 FILE *fp_out;
171 unsigned char *_guard_page;
172 int c;
173
174 if ((fp_res = fopen(TEST_NAME_RES, "w+")) == NULL) {
175 perror("fopen(" TEST_NAME_RES ")");
176 return 99;
177 }
178 if (sodium_init() != 0) {
179 return 99;
180 }
181 # if defined(__EMSCRIPTEN__) || defined(__SANITIZE_ADDRESS__)
182 guard_page = _guard_page = NULL;
183 #else
184 if ((_guard_page = (unsigned char *) sodium_malloc(0)) == NULL) {
185 perror("sodium_malloc()");
186 return 99;
187 }
188 guard_page = _guard_page + 1;
189 #endif
190 if (xmain() != 0) {
191 return 99;
192 }
193 rewind(fp_res);
194 if ((fp_out = fopen(TEST_NAME_OUT, "r")) == NULL) {
195 perror("fopen(" TEST_NAME_OUT ")");
196 return 99;
197 }
198 do {
199 if ((c = fgetc(fp_res)) != fgetc(fp_out)) {
200 return 99;
201 }
202 } while (c != EOF);
203 sodium_free(_guard_page);
204
205 return 0;
206 }
207
208 #undef printf
209 #define printf(...) fprintf(fp_res, __VA_ARGS__)
210
211 #else
212
main(void)213 int main(void)
214 {
215 if (sodium_init() != 0) {
216 return 99;
217 }
218 if (xmain() != 0) {
219 return 99;
220 }
221 printf("--- SUCCESS ---\n");
222
223 return 0;
224 }
225
226 #endif
227
228 #define main xmain
229
230 #endif
231