1/* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "apr_general.h" 18#include "apr_random.h" 19#include "apr_thread_proc.h" 20#include <stdio.h> 21#include <stdlib.h> 22#include "testutil.h" 23 24static void hexdump(const unsigned char *b, int n) 25{ 26 int i; 27 28 for (i = 0; i < n; ++i) { 29#if 0 30 if ((i & 0xf) == 0) 31 printf("%04x", i); 32 printf(" %02x", b[i]); 33 if ((i & 0xf) == 0xf) 34 printf("\n"); 35#else 36 printf("0x%02x,", b[i]); 37 if ((i & 7) == 7) 38 printf("\n"); 39#endif 40 } 41 printf("\n"); 42} 43 44static apr_random_t *r; 45 46typedef apr_status_t APR_THREAD_FUNC rnd_fn(apr_random_t * r, void *b, 47 apr_size_t n); 48 49static void rand_run_kat(abts_case *tc, rnd_fn *f, apr_random_t *r, 50 const unsigned char expected[128]) 51{ 52 unsigned char c[128]; 53 apr_status_t rv; 54 55 rv = f(r, c, 128); 56 ABTS_INT_EQUAL(tc, 0, rv); 57 if (rv) 58 return; 59 if (memcmp(c, expected, 128)) { 60 hexdump(c, 128); 61 hexdump(expected, 128); 62 ABTS_FAIL(tc, "Randomness mismatch"); 63 } 64} 65 66#if APR_HAS_FORK 67static int rand_check_kat(rnd_fn *f, apr_random_t *r, 68 const unsigned char expected[128]) 69{ 70 unsigned char c[128]; 71 apr_status_t rv; 72 73 rv = f(r, c, 128); 74 if (rv) 75 return 2; 76 if (memcmp(c, expected, 128)) 77 return 1; 78 return 0; 79} 80#endif 81 82static void rand_add_zeroes(apr_random_t *r) 83{ 84 static unsigned char c[2048]; 85 86 apr_random_add_entropy(r, c, sizeof c); 87} 88 89static void rand_run_seed_short(abts_case *tc, rnd_fn *f, apr_random_t *r, 90 int count) 91{ 92 int i; 93 apr_status_t rv; 94 char c[1]; 95 96 for (i = 0; i < count; ++i) 97 rand_add_zeroes(r); 98 rv = f(r, c, 1); 99 ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_ENOTENOUGHENTROPY(rv)); 100} 101 102static void rand_seed_short(abts_case *tc, void *data) 103{ 104 r = apr_random_standard_new(p); 105 rand_run_seed_short(tc, apr_random_insecure_bytes, r, 32); 106} 107 108static void rand_kat(abts_case *tc, void *data) 109{ 110 unsigned char expected[128] = { 111 0x82, 0x04, 0xad, 0xd2, 0x0b, 0xd5, 0xac, 0xda, 112 0x3d, 0x85, 0x58, 0x38, 0x54, 0x6b, 0x69, 0x45, 113 0x37, 0x4c, 0xc7, 0xd7, 0x87, 0xeb, 0xbf, 0xd9, 114 0xb1, 0xb8, 0xb8, 0x2d, 0x9b, 0x33, 0x6e, 0x97, 115 0x04, 0x1d, 0x4c, 0xb0, 0xd1, 0xdf, 0x3d, 0xac, 116 0xd2, 0xaa, 0xfa, 0xcd, 0x96, 0xb7, 0xcf, 0xb1, 117 0x8e, 0x3d, 0xb3, 0xe5, 0x37, 0xa9, 0x95, 0xb4, 118 0xaa, 0x3d, 0x11, 0x1a, 0x08, 0x20, 0x21, 0x9f, 119 0xdb, 0x08, 0x3a, 0xb9, 0x57, 0x9f, 0xf2, 0x1f, 120 0x27, 0xdc, 0xb6, 0xc0, 0x85, 0x08, 0x05, 0xbb, 121 0x13, 0xbe, 0xb1, 0xe9, 0x63, 0x2a, 0xe2, 0xa4, 122 0x23, 0x15, 0x2a, 0x10, 0xbf, 0xdf, 0x09, 0xb3, 123 0xc7, 0xfb, 0x2d, 0x87, 0x48, 0x19, 0xfb, 0xc0, 124 0x15, 0x8c, 0xcb, 0xc6, 0xbd, 0x89, 0x38, 0x69, 125 0xa3, 0xae, 0xa3, 0x21, 0x58, 0x50, 0xe7, 0xc4, 126 0x87, 0xec, 0x2e, 0xb1, 0x2d, 0x6a, 0xbd, 0x46 127 }; 128 129 rand_add_zeroes(r); 130 rand_run_kat(tc, apr_random_insecure_bytes, r, expected); 131} 132 133static void rand_seed_short2(abts_case *tc, void *data) 134{ 135 rand_run_seed_short(tc, apr_random_secure_bytes, r, 320); 136} 137 138static void rand_kat2(abts_case *tc, void *data) 139{ 140 unsigned char expected[128] = { 141 0x38, 0x8f, 0x01, 0x29, 0x5a, 0x5c, 0x1f, 0xa8, 142 0x00, 0xde, 0x16, 0x4c, 0xe5, 0xf7, 0x1f, 0x58, 143 0xc0, 0x67, 0xe2, 0x98, 0x3d, 0xde, 0x4a, 0x75, 144 0x61, 0x3f, 0x23, 0xd8, 0x45, 0x7a, 0x10, 0x60, 145 0x59, 0x9b, 0xd6, 0xaf, 0xcb, 0x0a, 0x2e, 0x34, 146 0x9c, 0x39, 0x5b, 0xd0, 0xbc, 0x9a, 0xf0, 0x7b, 147 0x7f, 0x40, 0x8b, 0x33, 0xc0, 0x0e, 0x2a, 0x56, 148 0xfc, 0xe5, 0xab, 0xde, 0x7b, 0x13, 0xf5, 0xec, 149 0x15, 0x68, 0xb8, 0x09, 0xbc, 0x2c, 0x15, 0xf0, 150 0x7b, 0xef, 0x2a, 0x97, 0x19, 0xa8, 0x69, 0x51, 151 0xdf, 0xb0, 0x5f, 0x1a, 0x4e, 0xdf, 0x42, 0x02, 152 0x71, 0x36, 0xa7, 0x25, 0x64, 0x85, 0xe2, 0x72, 153 0xc7, 0x87, 0x4d, 0x7d, 0x15, 0xbb, 0x15, 0xd1, 154 0xb1, 0x62, 0x0b, 0x25, 0xd9, 0xd3, 0xd9, 0x5a, 155 0xe3, 0x47, 0x1e, 0xae, 0x67, 0xb4, 0x19, 0x9e, 156 0xed, 0xd2, 0xde, 0xce, 0x18, 0x70, 0x57, 0x12 157 }; 158 159 rand_add_zeroes(r); 160 rand_run_kat(tc, apr_random_secure_bytes, r, expected); 161} 162 163static void rand_barrier(abts_case *tc, void *data) 164{ 165 apr_random_barrier(r); 166 rand_run_seed_short(tc, apr_random_secure_bytes, r, 320); 167} 168 169static void rand_kat3(abts_case *tc, void *data) 170{ 171 unsigned char expected[128] = { 172 0xe8, 0xe7, 0xc9, 0x45, 0xe2, 0x2a, 0x54, 0xb2, 173 0xdd, 0xe0, 0xf9, 0xbc, 0x3d, 0xf9, 0xce, 0x3c, 174 0x4c, 0xbd, 0xc9, 0xe2, 0x20, 0x4a, 0x35, 0x1c, 175 0x04, 0x52, 0x7f, 0xb8, 0x0f, 0x60, 0x89, 0x63, 176 0x8a, 0xbe, 0x0a, 0x44, 0xac, 0x5d, 0xd8, 0xeb, 177 0x24, 0x7d, 0xd1, 0xda, 0x4d, 0x86, 0x9b, 0x94, 178 0x26, 0x56, 0x4a, 0x5e, 0x30, 0xea, 0xd4, 0xa9, 179 0x9a, 0xdf, 0xdd, 0xb6, 0xb1, 0x15, 0xe0, 0xfa, 180 0x28, 0xa4, 0xd6, 0x95, 0xa4, 0xf1, 0xd8, 0x6e, 181 0xeb, 0x8c, 0xa4, 0xac, 0x34, 0xfe, 0x06, 0x92, 182 0xc5, 0x09, 0x99, 0x86, 0xdc, 0x5a, 0x3c, 0x92, 183 0xc8, 0x3e, 0x52, 0x00, 0x4d, 0x01, 0x43, 0x6f, 184 0x69, 0xcf, 0xe2, 0x60, 0x9c, 0x23, 0xb3, 0xa5, 185 0x5f, 0x51, 0x47, 0x8c, 0x07, 0xde, 0x60, 0xc6, 186 0x04, 0xbf, 0x32, 0xd6, 0xdc, 0xb7, 0x31, 0x01, 187 0x29, 0x51, 0x51, 0xb3, 0x19, 0x6e, 0xe4, 0xf8 188 }; 189 190 rand_run_kat(tc, apr_random_insecure_bytes, r, expected); 191} 192 193static void rand_kat4(abts_case *tc, void *data) 194{ 195 unsigned char expected[128] = { 196 0x7d, 0x0e, 0xc4, 0x4e, 0x3e, 0xac, 0x86, 0x50, 197 0x37, 0x95, 0x7a, 0x98, 0x23, 0x26, 0xa7, 0xbf, 198 0x60, 0xfb, 0xa3, 0x70, 0x90, 0xc3, 0x58, 0xc6, 199 0xbd, 0xd9, 0x5e, 0xa6, 0x77, 0x62, 0x7a, 0x5c, 200 0x96, 0x83, 0x7f, 0x80, 0x3d, 0xf4, 0x9c, 0xcc, 201 0x9b, 0x0c, 0x8c, 0xe1, 0x72, 0xa8, 0xfb, 0xc9, 202 0xc5, 0x43, 0x91, 0xdc, 0x9d, 0x92, 0xc2, 0xce, 203 0x1c, 0x5e, 0x36, 0xc7, 0x87, 0xb1, 0xb4, 0xa3, 204 0xc8, 0x69, 0x76, 0xfc, 0x35, 0x75, 0xcb, 0x08, 205 0x2f, 0xe3, 0x98, 0x76, 0x37, 0x80, 0x04, 0x5c, 206 0xb8, 0xb0, 0x7f, 0xb2, 0xda, 0xe3, 0xa3, 0xba, 207 0xed, 0xff, 0xf5, 0x9d, 0x3b, 0x7b, 0xf3, 0x32, 208 0x6c, 0x50, 0xa5, 0x3e, 0xcc, 0xe1, 0x84, 0x9c, 209 0x17, 0x9e, 0x80, 0x64, 0x09, 0xbb, 0x62, 0xf1, 210 0x95, 0xf5, 0x2c, 0xc6, 0x9f, 0x6a, 0xee, 0x6d, 211 0x17, 0x35, 0x5f, 0x35, 0x8d, 0x55, 0x0c, 0x07 212 }; 213 214 rand_add_zeroes(r); 215 rand_run_kat(tc, apr_random_secure_bytes, r, expected); 216} 217 218#if APR_HAS_FORK 219static void rand_fork(abts_case *tc, void *data) 220{ 221 apr_proc_t proc; 222 apr_status_t rv; 223 unsigned char expected[128] = { 224 0xac, 0x93, 0xd2, 0x5c, 0xc7, 0xf5, 0x8d, 0xc2, 225 0xd8, 0x8d, 0xb6, 0x7a, 0x94, 0xe1, 0x83, 0x4c, 226 0x26, 0xe2, 0x38, 0x6d, 0xf5, 0xbd, 0x9d, 0x6e, 227 0x91, 0x77, 0x3a, 0x4b, 0x9b, 0xef, 0x9b, 0xa3, 228 0x9f, 0xf6, 0x6d, 0x0c, 0xdc, 0x4b, 0x02, 0xe9, 229 0x5d, 0x3d, 0xfc, 0x92, 0x6b, 0xdf, 0xc9, 0xef, 230 0xb9, 0xa8, 0x74, 0x09, 0xa3, 0xff, 0x64, 0x8d, 231 0x19, 0xc1, 0x31, 0x31, 0x17, 0xe1, 0xb7, 0x7a, 232 0xe7, 0x55, 0x14, 0x92, 0x05, 0xe3, 0x1e, 0xb8, 233 0x9b, 0x1b, 0xdc, 0xac, 0x0e, 0x15, 0x08, 0xa2, 234 0x93, 0x13, 0xf6, 0x04, 0xc6, 0x9d, 0xf8, 0x7f, 235 0x26, 0x32, 0x68, 0x43, 0x2e, 0x5a, 0x4f, 0x47, 236 0xe8, 0xf8, 0x59, 0xb7, 0xfb, 0xbe, 0x30, 0x04, 237 0xb6, 0x63, 0x6f, 0x19, 0xf3, 0x2c, 0xd4, 0xeb, 238 0x32, 0x8a, 0x54, 0x01, 0xd0, 0xaf, 0x3f, 0x13, 239 0xc1, 0x7f, 0x10, 0x2e, 0x08, 0x1c, 0x28, 0x4b, 240 }; 241 242 rv = apr_proc_fork(&proc, p); 243 if (rv == APR_INCHILD) { 244 int n = rand_check_kat(apr_random_secure_bytes, r, expected); 245 exit(n); 246 } 247 else if (rv == APR_INPARENT) { 248 int exitcode; 249 apr_exit_why_e why; 250 251 rand_run_kat(tc, apr_random_secure_bytes, r, expected); 252 apr_proc_wait(&proc, &exitcode, &why, APR_WAIT); 253 if (why != APR_PROC_EXIT) { 254 ABTS_FAIL(tc, "Child terminated abnormally"); 255 } 256 else if (exitcode == 0) { 257 ABTS_FAIL(tc, "Child produced our randomness"); 258 } 259 else if (exitcode == 2) { 260 ABTS_FAIL(tc, "Child randomness failed"); 261 } 262 else if (exitcode != 1) { 263 ABTS_FAIL(tc, "Uknown child error"); 264 } 265 } else { 266 ABTS_FAIL(tc, "Fork failed"); 267 } 268} 269#endif 270 271static void rand_exists(abts_case *tc, void *data) 272{ 273#if !APR_HAS_RANDOM 274 ABTS_NOT_IMPL(tc, "apr_generate_random_bytes"); 275#else 276 unsigned char c[42]; 277 278 /* There must be a better way to test random-ness, but I don't know 279 * what it is right now. 280 */ 281 APR_ASSERT_SUCCESS(tc, "apr_generate_random_bytes failed", 282 apr_generate_random_bytes(c, sizeof c)); 283#endif 284} 285 286abts_suite *testrand(abts_suite *suite) 287{ 288 suite = ADD_SUITE(suite) 289 290 abts_run_test(suite, rand_exists, NULL); 291 abts_run_test(suite, rand_seed_short, NULL); 292 abts_run_test(suite, rand_kat, NULL); 293 abts_run_test(suite, rand_seed_short2, NULL); 294 abts_run_test(suite, rand_kat2, NULL); 295 abts_run_test(suite, rand_barrier, NULL); 296 abts_run_test(suite, rand_kat3, NULL); 297 abts_run_test(suite, rand_kat4, NULL); 298#if APR_HAS_FORK 299 abts_run_test(suite, rand_fork, NULL); 300#endif 301 302 return suite; 303} 304