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