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 #ifdef BENCHMARKS
39 
40 # include <sys/time.h>
41 
42 # ifndef ITERATIONS
43 #  define ITERATIONS 128
44 # endif
45 
46 struct {
47     void   *pnt;
48     size_t  size;
49 } mempool[1024];
50 
51 static size_t mempool_idx;
52 
mempool_alloc(size_t size)53 static __attribute__((malloc)) void *mempool_alloc(size_t size)
54 {
55     size_t i;
56     if (size >= (size_t) 0x80000000 - (size_t) 0x00000fff) {
57         return NULL;
58     }
59     size = (size + (size_t) 0x00000fff) & ~ (size_t) 0x00000fff;
60     for (i = 0U; i < mempool_idx; i++) {
61         if (mempool[i].size >= (size | (size_t) 0x80000000)) {
62             mempool[i].size &= ~ (size_t) 0x80000000;
63             return mempool[i].pnt;
64         }
65     }
66     if (mempool_idx >= sizeof mempool / sizeof mempool[0]) {
67         return NULL;
68     }
69     mempool[mempool_idx].size = size;
70     return (mempool[mempool_idx++].pnt = (void *) malloc(size));
71 }
72 
mempool_free(void * pnt)73 static void mempool_free(void *pnt)
74 {
75     size_t i;
76     for (i = 0U; i < mempool_idx; i++) {
77         if (mempool[i].pnt == pnt) {
78             if ((mempool[i].size & (size_t) 0x80000000) != (size_t) 0x0) {
79                 break;
80             }
81             mempool[i].size |= (size_t) 0x80000000;
82             return;
83         }
84     }
85     abort();
86 }
87 
mempool_allocarray(size_t count,size_t size)88 static __attribute__((malloc)) void *mempool_allocarray(size_t count, size_t size)
89 {
90     if (count > (size_t) 0U && size >= (size_t) SIZE_MAX / count) {
91         return NULL;
92     }
93     return mempool_alloc(count * size);
94 }
95 
mempool_free_all(void)96 static int mempool_free_all(void)
97 {
98     size_t i;
99     int    ret = 0;
100 
101     for (i = 0U; i < mempool_idx; i++) {
102         if ((mempool[i].size & (size_t) 0x80000000) == (size_t) 0x0) {
103             ret = -1;
104         }
105         free(mempool[i].pnt);
106         mempool[i].pnt = NULL;
107     }
108     mempool_idx = (size_t) 0U;
109 
110     return ret;
111 }
112 
113 #define sodium_malloc(X)        mempool_alloc(X)
114 #define sodium_free(X)          mempool_free(X)
115 #define sodium_allocarray(X, Y) mempool_allocarray((X), (Y))
116 
now(void)117 static unsigned long long now(void)
118 {
119     struct             timeval tp;
120     unsigned long long now;
121 
122     if (gettimeofday(&tp, NULL) != 0) {
123         abort();
124     }
125     now = ((unsigned long long) tp.tv_sec * 1000000ULL) +
126         (unsigned long long) tp.tv_usec;
127 
128     return now;
129 }
130 
main(void)131 int main(void)
132 {
133     unsigned long long ts_start;
134     unsigned long long ts_end;
135     unsigned int       i;
136 
137     if (sodium_init() != 0) {
138         return 99;
139     }
140 
141 #ifndef __EMSCRIPTEN__
142     randombytes_set_implementation(&randombytes_salsa20_implementation);
143 #endif
144     ts_start = now();
145     for (i = 0; i < ITERATIONS; i++) {
146         if (xmain() != 0) {
147             abort();
148         }
149     }
150     ts_end = now();
151     printf("%llu\n", 1000000ULL * (ts_end - ts_start) / ITERATIONS);
152     if (mempool_free_all() != 0) {
153         fprintf(stderr, "** memory leaks detected **\n");
154         return 99;
155     }
156     return 0;
157 }
158 
159 #undef  printf
160 #define printf(...) do { } while(0)
161 
162 #elif !defined(BROWSER_TESTS)
163 
164 static FILE *fp_res;
165 
main(void)166 int main(void)
167 {
168     FILE *fp_out;
169     int   c;
170 
171     if ((fp_res = fopen(TEST_NAME_RES, "w+")) == NULL) {
172         perror("fopen(" TEST_NAME_RES ")");
173         return 99;
174     }
175     if (sodium_init() != 0) {
176         return 99;
177     }
178     if (xmain() != 0) {
179         return 99;
180     }
181     rewind(fp_res);
182     if ((fp_out = fopen(TEST_NAME_OUT, "r")) == NULL) {
183         perror("fopen(" TEST_NAME_OUT ")");
184         return 99;
185     }
186     do {
187         if ((c = fgetc(fp_res)) != fgetc(fp_out)) {
188             return 99;
189         }
190     } while (c != EOF);
191 
192     return 0;
193 }
194 
195 #undef  printf
196 #define printf(...) fprintf(fp_res, __VA_ARGS__)
197 
198 #else
199 
main(void)200 int main(void)
201 {
202     if (sodium_init() != 0) {
203         return 99;
204     }
205     if (xmain() != 0) {
206         return 99;
207     }
208     printf("--- SUCCESS ---\n");
209 
210     return 0;
211 }
212 
213 #endif
214 
215 #define main xmain
216 
217 #endif
218