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