16ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org/*
26ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org * stat-driver.c
36ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org *
46ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org * test driver for the stat_test functions
56ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org *
66ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org * David A. McGrew
76ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org * Cisco Systems, Inc.
86ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org */
96ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org
105961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com/*
115961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com *
125961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * Copyright (c) 2001-2006, Cisco Systems, Inc.
135961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * All rights reserved.
145961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com *
155961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * Redistribution and use in source and binary forms, with or without
165961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * modification, are permitted provided that the following conditions
175961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * are met:
185961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com *
195961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com *   Redistributions of source code must retain the above copyright
205961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com *   notice, this list of conditions and the following disclaimer.
215961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com *
225961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com *   Redistributions in binary form must reproduce the above
235961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com *   copyright notice, this list of conditions and the following
245961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com *   disclaimer in the documentation and/or other materials provided
255961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com *   with the distribution.
265961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com *
275961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com *   Neither the name of the Cisco Systems, Inc. nor the names of its
285961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com *   contributors may be used to endorse or promote products derived
295961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com *   from this software without specific prior written permission.
305961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com *
315961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
325961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
335961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
345961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
355961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
365961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
375961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
385961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
395961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
405961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
415961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
425961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com * OF THE POSSIBILITY OF SUCH DAMAGE.
435961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com *
445961d8555973f660a94b77ffd7b9495291fbc874mallinath@google.com */
456ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org
466ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org#include <stdio.h>         /* for printf() */
476ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org
486ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org#include "err.h"
496ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org#include "stat.h"
506ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org
516ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org#include "cipher.h"
526ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org
536ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.orgtypedef struct {
546ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  void *state;
556ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org} random_source_t;
566ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org
576ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.orgerr_status_t
586ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.orgrandom_source_alloc(void);
596ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org
606ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.orgvoid
616ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.orgerr_check(err_status_t s) {
626ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  if (s) {
636ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    printf("error (code %d)\n", s);
646ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    exit(1);
656ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  }
666ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org}
676ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org
686ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.orgint
696ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.orgmain (int argc, char *argv[]) {
706ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  uint8_t buffer[2500];
716ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  unsigned int buf_len = 2500;
726ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  int i, j;
736ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  extern cipher_type_t aes_icm;
746ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  cipher_t *c;
756ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  uint8_t key[46] = {
766ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
776ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
786ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
796ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
806ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
816ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    0x00, 0x01, 0x02, 0x03, 0x04, 0x05
826ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    };
836ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  v128_t nonce;
846ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  int num_trials = 500;
856ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  int num_fail;
866ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org
876ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("statistical tests driver\n");
886ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org
896ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  for (i=0; i < 2500; i++)
906ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    buffer[i] = 0;
916ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org
926ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  /* run tests */
936ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("running stat_tests on all-null buffer, expecting failure\n");
946ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("monobit %d\n", stat_test_monobit(buffer));
956ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("poker   %d\n", stat_test_poker(buffer));
966ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("runs    %d\n", stat_test_runs(buffer));
976ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org
986ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  for (i=0; i < 2500; i++)
996ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    buffer[i] = rand();
1006ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("running stat_tests on rand(), expecting success\n");
1016ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("monobit %d\n", stat_test_monobit(buffer));
1026ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("poker   %d\n", stat_test_poker(buffer));
1036ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("runs    %d\n", stat_test_runs(buffer));
1046ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org
1056ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("running stat_tests on AES-128-ICM, expecting success\n");
1066ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  /* set buffer to cipher output */
1076ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  for (i=0; i < 2500; i++)
1086ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    buffer[i] = 0;
1096ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  err_check(cipher_type_alloc(&aes_icm, &c, 30));
1106ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  err_check(cipher_init(c, key, direction_encrypt));
1116ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  err_check(cipher_set_iv(c, &nonce));
1126ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  err_check(cipher_encrypt(c, buffer, &buf_len));
1136ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  /* run tests on cipher outout */
1146ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("monobit %d\n", stat_test_monobit(buffer));
1156ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("poker   %d\n", stat_test_poker(buffer));
1166ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("runs    %d\n", stat_test_runs(buffer));
1176ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org
1186ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("runs test (please be patient): ");
1196ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  fflush(stdout);
1206ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  num_fail = 0;
1216ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  v128_set_to_zero(&nonce);
1226ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  for(j=0; j < num_trials; j++) {
1236ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    for (i=0; i < 2500; i++)
1246ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org      buffer[i] = 0;
1256ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    nonce.v32[3] = i;
1266ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    err_check(cipher_set_iv(c, &nonce));
1276ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    err_check(cipher_encrypt(c, buffer, &buf_len));
1286ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    if (stat_test_runs(buffer)) {
1296ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org      num_fail++;
1306ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    }
1316ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  }
1326ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org
1336ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("%d failures in %d tests\n", num_fail, num_trials);
1346ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("(nota bene: a small fraction of stat_test failures does not \n"
1356ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org	 "indicate that the random source is invalid)\n");
1366ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org
1376ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  err_check(cipher_dealloc(c));
1386ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org
1396ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("running stat_tests on AES-256-ICM, expecting success\n");
1406ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  /* set buffer to cipher output */
1416ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  for (i=0; i < 2500; i++)
1426ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    buffer[i] = 0;
1436ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  err_check(cipher_type_alloc(&aes_icm, &c, 46));
1446ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  err_check(cipher_init(c, key, direction_encrypt));
1456ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  err_check(cipher_set_iv(c, &nonce));
1466ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  err_check(cipher_encrypt(c, buffer, &buf_len));
1476ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  /* run tests on cipher outout */
1486ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("monobit %d\n", stat_test_monobit(buffer));
1496ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("poker   %d\n", stat_test_poker(buffer));
1506ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("runs    %d\n", stat_test_runs(buffer));
1516ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org
1526ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("runs test (please be patient): ");
1536ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  fflush(stdout);
1546ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  num_fail = 0;
1556ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  v128_set_to_zero(&nonce);
1566ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  for(j=0; j < num_trials; j++) {
1576ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    for (i=0; i < 2500; i++)
1586ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org      buffer[i] = 0;
1596ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    nonce.v32[3] = i;
1606ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    err_check(cipher_set_iv(c, &nonce));
1616ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    err_check(cipher_encrypt(c, buffer, &buf_len));
1626ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    if (stat_test_runs(buffer)) {
1636ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org      num_fail++;
1646ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org    }
1656ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  }
1666ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org
1676ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("%d failures in %d tests\n", num_fail, num_trials);
1686ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  printf("(nota bene: a small fraction of stat_test failures does not \n"
1696ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org	 "indicate that the random source is invalid)\n");
1706ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org
1716ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  err_check(cipher_dealloc(c));
1726ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org
1736ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org  return 0;
1746ed0ee98e1c3d29a0ef79996f7d1abf174f39besergeyu@chromium.org}
175