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
36int xmain(void);
37
38#ifdef BENCHMARKS
39
40# include <sys/time.h>
41
42# ifndef ITERATIONS
43#  define ITERATIONS 128
44# endif
45
46struct {
47    void   *pnt;
48    size_t  size;
49} mempool[1024];
50
51static size_t mempool_idx;
52
53static __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
73static 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
88static __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
96static 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
117static 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
131int 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
164static FILE *fp_res;
165
166int 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
200int 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