1 /* 2 * stats.c 3 * 4 * statistical tests for randomness (FIPS 140-2, Section 4.9) 5 * 6 * David A. McGrew 7 * Cisco Systems, Inc. 8 */ 9 10 #include "stat.h" 11 12 debug_module_t mod_stat = { 13 0, /* debugging is off by default */ 14 (char *)"stat test" /* printable module name */ 15 }; 16 17 /* 18 * each test assumes that 20,000 bits (2500 octets) of data is 19 * provided as input 20 */ 21 22 #define STAT_TEST_DATA_LEN 2500 23 24 err_status_t 25 stat_test_monobit(uint8_t *data) { 26 uint8_t *data_end = data + STAT_TEST_DATA_LEN; 27 uint16_t ones_count; 28 29 ones_count = 0; 30 while (data < data_end) { 31 ones_count += octet_get_weight(*data); 32 data++; 33 } 34 35 debug_print(mod_stat, "bit count: %d", ones_count); 36 37 if ((ones_count < 9725) || (ones_count > 10275)) 38 return err_status_algo_fail; 39 40 return err_status_ok; 41 } 42 43 err_status_t 44 stat_test_poker(uint8_t *data) { 45 int i; 46 uint8_t *data_end = data + STAT_TEST_DATA_LEN; 47 double poker; 48 uint16_t f[16] = { 49 0, 0, 0, 0, 0, 0, 0, 0, 50 0, 0, 0, 0, 0, 0, 0, 0 51 }; 52 53 while (data < data_end) { 54 f[*data & 0x0f]++; /* increment freq. count for low nibble */ 55 f[(*data) >> 4]++; /* increment freq. count for high nibble */ 56 data++; 57 } 58 59 poker = 0.0; 60 for (i=0; i < 16; i++) 61 poker += (double) f[i] * f[i]; 62 63 poker *= (16.0 / 5000.0); 64 poker -= 5000.0; 65 66 debug_print(mod_stat, "poker test: %f\n", poker); 67 68 if ((poker < 2.16) || (poker > 46.17)) 69 return err_status_algo_fail; 70 71 return err_status_ok; 72 } 73 74 75 /* 76 * runs[i] holds the number of runs of size (i-1) 77 */ 78 79 err_status_t 80 stat_test_runs(uint8_t *data) { 81 uint8_t *data_end = data + STAT_TEST_DATA_LEN; 82 uint16_t runs[6] = { 0, 0, 0, 0, 0, 0 }; 83 uint16_t gaps[6] = { 0, 0, 0, 0, 0, 0 }; 84 uint16_t lo_value[6] = { 2315, 1114, 527, 240, 103, 103 }; 85 uint16_t hi_value[6] = { 2685, 1386, 723, 384, 209, 209 }; 86 int state = 0; 87 uint16_t mask; 88 int i; 89 90 /* 91 * the state variable holds the number of bits in the 92 * current run (or gap, if negative) 93 */ 94 95 while (data < data_end) { 96 97 /* loop over the bits of this byte */ 98 for (mask = 1; mask < 256; mask <<= 1) { 99 if (*data & mask) { 100 101 /* next bit is a one */ 102 if (state > 0) { 103 104 /* prefix is a run, so increment the run-count */ 105 state++; 106 107 /* check for long runs */ 108 if (state > 25) { 109 debug_print(mod_stat, ">25 runs: %d", state); 110 return err_status_algo_fail; 111 } 112 113 } else if (state < 0) { 114 115 /* prefix is a gap */ 116 if (state < -25) { 117 debug_print(mod_stat, ">25 gaps: %d", state); 118 return err_status_algo_fail; /* long-runs test failed */ 119 } 120 if (state < -6) { 121 state = -6; /* group together gaps > 5 */ 122 } 123 gaps[-1-state]++; /* increment gap count */ 124 state = 1; /* set state at one set bit */ 125 } else { 126 127 /* state is zero; this happens only at initialization */ 128 state = 1; 129 } 130 } else { 131 132 /* next bit is a zero */ 133 if (state > 0) { 134 135 /* prefix is a run */ 136 if (state > 25) { 137 debug_print(mod_stat, ">25 runs (2): %d", state); 138 return err_status_algo_fail; /* long-runs test failed */ 139 } 140 if (state > 6) { 141 state = 6; /* group together runs > 5 */ 142 } 143 runs[state-1]++; /* increment run count */ 144 state = -1; /* set state at one zero bit */ 145 } else if (state < 0) { 146 147 /* prefix is a gap, so increment gap-count (decrement state) */ 148 state--; 149 150 /* check for long gaps */ 151 if (state < -25) { 152 debug_print(mod_stat, ">25 gaps (2): %d", state); 153 return err_status_algo_fail; 154 } 155 156 } else { 157 158 /* state is zero; this happens only at initialization */ 159 state = -1; 160 } 161 } 162 } 163 164 /* move along to next octet */ 165 data++; 166 } 167 168 if (mod_stat.on) { 169 debug_print(mod_stat, "runs test", NULL); 170 for (i=0; i < 6; i++) 171 debug_print(mod_stat, " runs[]: %d", runs[i]); 172 for (i=0; i < 6; i++) 173 debug_print(mod_stat, " gaps[]: %d", gaps[i]); 174 } 175 176 /* check run and gap counts against the fixed limits */ 177 for (i=0; i < 6; i++) 178 if ( (runs[i] < lo_value[i] ) || (runs[i] > hi_value[i]) 179 || (gaps[i] < lo_value[i] ) || (gaps[i] > hi_value[i])) 180 return err_status_algo_fail; 181 182 183 return err_status_ok; 184 } 185 186 187 /* 188 * the function stat_test_rand_source applys the FIPS-140-2 statistical 189 * tests to the random source defined by rs 190 * 191 */ 192 193 #define RAND_SRC_BUF_OCTETS 50 /* this value MUST divide 2500! */ 194 195 err_status_t 196 stat_test_rand_source(rand_source_func_t get_rand_bytes) { 197 int i; 198 double poker; 199 uint8_t *data, *data_end; 200 uint16_t f[16] = { 201 0, 0, 0, 0, 0, 0, 0, 0, 202 0, 0, 0, 0, 0, 0, 0, 0 203 }; 204 uint8_t buffer[RAND_SRC_BUF_OCTETS]; 205 err_status_t status; 206 int ones_count = 0; 207 uint16_t runs[6] = { 0, 0, 0, 0, 0, 0 }; 208 uint16_t gaps[6] = { 0, 0, 0, 0, 0, 0 }; 209 uint16_t lo_value[6] = { 2315, 1114, 527, 240, 103, 103 }; 210 uint16_t hi_value[6] = { 2685, 1386, 723, 384, 209, 209 }; 211 int state = 0; 212 uint16_t mask; 213 214 /* counters for monobit, poker, and runs tests are initialized above */ 215 216 /* main loop: fill buffer, update counters for stat tests */ 217 for (i=0; i < 2500; i+=RAND_SRC_BUF_OCTETS) { 218 219 /* fill data buffer */ 220 status = get_rand_bytes(buffer, RAND_SRC_BUF_OCTETS); 221 if (status) { 222 debug_print(mod_stat, "couldn't get rand bytes: %d",status); 223 return status; 224 } 225 226 #if 0 227 debug_print(mod_stat, "%s", 228 octet_string_hex_string(buffer, RAND_SRC_BUF_OCTETS)); 229 #endif 230 231 data = buffer; 232 data_end = data + RAND_SRC_BUF_OCTETS; 233 while (data < data_end) { 234 235 /* update monobit test counter */ 236 ones_count += octet_get_weight(*data); 237 238 /* update poker test counters */ 239 f[*data & 0x0f]++; /* increment freq. count for low nibble */ 240 f[(*data) >> 4]++; /* increment freq. count for high nibble */ 241 242 /* update runs test counters */ 243 /* loop over the bits of this byte */ 244 for (mask = 1; mask < 256; mask <<= 1) { 245 if (*data & mask) { 246 247 /* next bit is a one */ 248 if (state > 0) { 249 250 /* prefix is a run, so increment the run-count */ 251 state++; 252 253 /* check for long runs */ 254 if (state > 25) { 255 debug_print(mod_stat, ">25 runs (3): %d", state); 256 return err_status_algo_fail; 257 } 258 259 } else if (state < 0) { 260 261 /* prefix is a gap */ 262 if (state < -25) { 263 debug_print(mod_stat, ">25 gaps (3): %d", state); 264 return err_status_algo_fail; /* long-runs test failed */ 265 } 266 if (state < -6) { 267 state = -6; /* group together gaps > 5 */ 268 } 269 gaps[-1-state]++; /* increment gap count */ 270 state = 1; /* set state at one set bit */ 271 } else { 272 273 /* state is zero; this happens only at initialization */ 274 state = 1; 275 } 276 } else { 277 278 /* next bit is a zero */ 279 if (state > 0) { 280 281 /* prefix is a run */ 282 if (state > 25) { 283 debug_print(mod_stat, ">25 runs (4): %d", state); 284 return err_status_algo_fail; /* long-runs test failed */ 285 } 286 if (state > 6) { 287 state = 6; /* group together runs > 5 */ 288 } 289 runs[state-1]++; /* increment run count */ 290 state = -1; /* set state at one zero bit */ 291 } else if (state < 0) { 292 293 /* prefix is a gap, so increment gap-count (decrement state) */ 294 state--; 295 296 /* check for long gaps */ 297 if (state < -25) { 298 debug_print(mod_stat, ">25 gaps (4): %d", state); 299 return err_status_algo_fail; 300 } 301 302 } else { 303 304 /* state is zero; this happens only at initialization */ 305 state = -1; 306 } 307 } 308 } 309 310 /* advance data pointer */ 311 data++; 312 } 313 } 314 315 /* check to see if test data is within bounds */ 316 317 /* check monobit test data */ 318 319 debug_print(mod_stat, "stat: bit count: %d", ones_count); 320 321 if ((ones_count < 9725) || (ones_count > 10275)) { 322 debug_print(mod_stat, "stat: failed monobit test %d", ones_count); 323 return err_status_algo_fail; 324 } 325 326 /* check poker test data */ 327 poker = 0.0; 328 for (i=0; i < 16; i++) 329 poker += (double) f[i] * f[i]; 330 331 poker *= (16.0 / 5000.0); 332 poker -= 5000.0; 333 334 debug_print(mod_stat, "stat: poker test: %f", poker); 335 336 if ((poker < 2.16) || (poker > 46.17)) { 337 debug_print(mod_stat, "stat: failed poker test", NULL); 338 return err_status_algo_fail; 339 } 340 341 /* check run and gap counts against the fixed limits */ 342 for (i=0; i < 6; i++) 343 if ((runs[i] < lo_value[i] ) || (runs[i] > hi_value[i]) 344 || (gaps[i] < lo_value[i] ) || (gaps[i] > hi_value[i])) { 345 debug_print(mod_stat, "stat: failed run/gap test", NULL); 346 return err_status_algo_fail; 347 } 348 349 debug_print(mod_stat, "passed random stat test", NULL); 350 return err_status_ok; 351 } 352 353 err_status_t 354 stat_test_rand_source_with_repetition(rand_source_func_t source, unsigned num_trials) { 355 unsigned int i; 356 err_status_t err = err_status_algo_fail; 357 358 for (i=0; i < num_trials; i++) { 359 err = stat_test_rand_source(source); 360 if (err == err_status_ok) { 361 return err_status_ok; 362 } 363 debug_print(mod_stat, "failed stat test (try number %d)\n", i); 364 } 365 366 return err; 367 } 368