cmptest.h (4956B)
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 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 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 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 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 119 static unsigned long long now(void) 120 { 121 #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) 122 struct timespec tp; 123 124 if (clock_gettime(CLOCK_MONOTONIC, &tp) != 0) { 125 abort(); 126 } 127 return (unsigned long long) tp.tv_sec * 1000000ULL + 128 (unsigned long long) tp.tv_nsec / 1000ULL; 129 #else 130 struct timeval tp; 131 132 if (gettimeofday(&tp, NULL) != 0) { 133 abort(); 134 } 135 return (unsigned long long) tp.tv_sec * 1000000ULL + 136 (unsigned long long) tp.tv_usec; 137 #endif 138 } 139 140 int main(void) 141 { 142 unsigned long long ts_start; 143 unsigned long long ts_end; 144 unsigned int i; 145 146 if (sodium_init() != 0) { 147 return 99; 148 } 149 150 #ifndef __EMSCRIPTEN__ 151 randombytes_set_implementation(&randombytes_salsa20_implementation); 152 #endif 153 ts_start = now(); 154 for (i = 0; i < ITERATIONS; i++) { 155 if (xmain() != 0) { 156 abort(); 157 } 158 } 159 ts_end = now(); 160 printf("%llu\n", 1000000ULL * (ts_end - ts_start) / ITERATIONS); 161 if (mempool_free_all() != 0) { 162 fprintf(stderr, "** memory leaks detected **\n"); 163 return 99; 164 } 165 return 0; 166 } 167 168 #undef printf 169 #define printf(...) do { } while(0) 170 171 #elif !defined(BROWSER_TESTS) 172 173 static FILE *fp_res; 174 175 int main(void) 176 { 177 FILE *fp_out; 178 unsigned char *_guard_page; 179 int c; 180 181 if ((fp_res = fopen(TEST_NAME_RES, "w+")) == NULL) { 182 perror("fopen(" TEST_NAME_RES ")"); 183 return 99; 184 } 185 if (sodium_init() != 0) { 186 return 99; 187 } 188 # if defined(__EMSCRIPTEN__) || defined(__SANITIZE_ADDRESS__) 189 guard_page = _guard_page = NULL; 190 #else 191 if ((_guard_page = (unsigned char *) sodium_malloc(0)) == NULL) { 192 perror("sodium_malloc()"); 193 return 99; 194 } 195 guard_page = _guard_page + 1; 196 #endif 197 if (xmain() != 0) { 198 return 99; 199 } 200 fflush(fp_res); 201 rewind(fp_res); 202 if ((fp_out = fopen(TEST_NAME_OUT, "r")) == NULL) { 203 perror("fopen(" TEST_NAME_OUT ")"); 204 return 99; 205 } 206 do { 207 if ((c = fgetc(fp_res)) != fgetc(fp_out)) { 208 return 99; 209 } 210 } while (c != EOF); 211 sodium_free(_guard_page); 212 213 return 0; 214 } 215 216 #undef printf 217 #define printf(...) fprintf(fp_res, __VA_ARGS__) 218 219 #else 220 221 int main(void) 222 { 223 if (sodium_init() != 0) { 224 return 99; 225 } 226 if (xmain() != 0) { 227 return 99; 228 } 229 printf("--- SUCCESS ---\n"); 230 231 return 0; 232 } 233 234 #endif 235 236 #define main xmain 237 238 #endif