1*90e502c7SAndroid Build Coastguard Worker /*
2*90e502c7SAndroid Build Coastguard Worker * stat-driver.c
3*90e502c7SAndroid Build Coastguard Worker *
4*90e502c7SAndroid Build Coastguard Worker * test driver for the stat_test functions
5*90e502c7SAndroid Build Coastguard Worker *
6*90e502c7SAndroid Build Coastguard Worker * David A. McGrew
7*90e502c7SAndroid Build Coastguard Worker * Cisco Systems, Inc.
8*90e502c7SAndroid Build Coastguard Worker */
9*90e502c7SAndroid Build Coastguard Worker
10*90e502c7SAndroid Build Coastguard Worker /*
11*90e502c7SAndroid Build Coastguard Worker *
12*90e502c7SAndroid Build Coastguard Worker * Copyright (c) 2001-2017, Cisco Systems, Inc.
13*90e502c7SAndroid Build Coastguard Worker * All rights reserved.
14*90e502c7SAndroid Build Coastguard Worker *
15*90e502c7SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
16*90e502c7SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
17*90e502c7SAndroid Build Coastguard Worker * are met:
18*90e502c7SAndroid Build Coastguard Worker *
19*90e502c7SAndroid Build Coastguard Worker * Redistributions of source code must retain the above copyright
20*90e502c7SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
21*90e502c7SAndroid Build Coastguard Worker *
22*90e502c7SAndroid Build Coastguard Worker * Redistributions in binary form must reproduce the above
23*90e502c7SAndroid Build Coastguard Worker * copyright notice, this list of conditions and the following
24*90e502c7SAndroid Build Coastguard Worker * disclaimer in the documentation and/or other materials provided
25*90e502c7SAndroid Build Coastguard Worker * with the distribution.
26*90e502c7SAndroid Build Coastguard Worker *
27*90e502c7SAndroid Build Coastguard Worker * Neither the name of the Cisco Systems, Inc. nor the names of its
28*90e502c7SAndroid Build Coastguard Worker * contributors may be used to endorse or promote products derived
29*90e502c7SAndroid Build Coastguard Worker * from this software without specific prior written permission.
30*90e502c7SAndroid Build Coastguard Worker *
31*90e502c7SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32*90e502c7SAndroid Build Coastguard Worker * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33*90e502c7SAndroid Build Coastguard Worker * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
34*90e502c7SAndroid Build Coastguard Worker * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
35*90e502c7SAndroid Build Coastguard Worker * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
36*90e502c7SAndroid Build Coastguard Worker * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37*90e502c7SAndroid Build Coastguard Worker * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
38*90e502c7SAndroid Build Coastguard Worker * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39*90e502c7SAndroid Build Coastguard Worker * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40*90e502c7SAndroid Build Coastguard Worker * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41*90e502c7SAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
42*90e502c7SAndroid Build Coastguard Worker * OF THE POSSIBILITY OF SUCH DAMAGE.
43*90e502c7SAndroid Build Coastguard Worker *
44*90e502c7SAndroid Build Coastguard Worker */
45*90e502c7SAndroid Build Coastguard Worker
46*90e502c7SAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
47*90e502c7SAndroid Build Coastguard Worker #include <config.h>
48*90e502c7SAndroid Build Coastguard Worker #endif
49*90e502c7SAndroid Build Coastguard Worker
50*90e502c7SAndroid Build Coastguard Worker #include <stdio.h> /* for printf() */
51*90e502c7SAndroid Build Coastguard Worker
52*90e502c7SAndroid Build Coastguard Worker #include "err.h"
53*90e502c7SAndroid Build Coastguard Worker #include "stat.h"
54*90e502c7SAndroid Build Coastguard Worker #include "srtp.h"
55*90e502c7SAndroid Build Coastguard Worker
56*90e502c7SAndroid Build Coastguard Worker #include "cipher.h"
57*90e502c7SAndroid Build Coastguard Worker #include "cipher_priv.h"
58*90e502c7SAndroid Build Coastguard Worker
err_check(srtp_err_status_t s)59*90e502c7SAndroid Build Coastguard Worker void err_check(srtp_err_status_t s)
60*90e502c7SAndroid Build Coastguard Worker {
61*90e502c7SAndroid Build Coastguard Worker if (s) {
62*90e502c7SAndroid Build Coastguard Worker printf("error (code %d)\n", s);
63*90e502c7SAndroid Build Coastguard Worker exit(1);
64*90e502c7SAndroid Build Coastguard Worker }
65*90e502c7SAndroid Build Coastguard Worker }
66*90e502c7SAndroid Build Coastguard Worker
main(int argc,char * argv[])67*90e502c7SAndroid Build Coastguard Worker int main(int argc, char *argv[])
68*90e502c7SAndroid Build Coastguard Worker {
69*90e502c7SAndroid Build Coastguard Worker uint8_t buffer[2532];
70*90e502c7SAndroid Build Coastguard Worker unsigned int buf_len = 2500;
71*90e502c7SAndroid Build Coastguard Worker int i, j;
72*90e502c7SAndroid Build Coastguard Worker extern srtp_cipher_type_t srtp_aes_icm_128;
73*90e502c7SAndroid Build Coastguard Worker extern srtp_cipher_type_t srtp_aes_icm_256;
74*90e502c7SAndroid Build Coastguard Worker #ifdef GCM
75*90e502c7SAndroid Build Coastguard Worker extern srtp_cipher_type_t srtp_aes_gcm_128;
76*90e502c7SAndroid Build Coastguard Worker extern srtp_cipher_type_t srtp_aes_gcm_256;
77*90e502c7SAndroid Build Coastguard Worker #endif
78*90e502c7SAndroid Build Coastguard Worker srtp_cipher_t *c;
79*90e502c7SAndroid Build Coastguard Worker /* clang-format off */
80*90e502c7SAndroid Build Coastguard Worker uint8_t key[46] = {
81*90e502c7SAndroid Build Coastguard Worker 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
82*90e502c7SAndroid Build Coastguard Worker 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
83*90e502c7SAndroid Build Coastguard Worker 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
84*90e502c7SAndroid Build Coastguard Worker 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
85*90e502c7SAndroid Build Coastguard Worker 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
86*90e502c7SAndroid Build Coastguard Worker 0x00, 0x01, 0x02, 0x03, 0x04, 0x05
87*90e502c7SAndroid Build Coastguard Worker };
88*90e502c7SAndroid Build Coastguard Worker /* clang-format on */
89*90e502c7SAndroid Build Coastguard Worker v128_t nonce;
90*90e502c7SAndroid Build Coastguard Worker int num_trials = 500;
91*90e502c7SAndroid Build Coastguard Worker int num_fail;
92*90e502c7SAndroid Build Coastguard Worker
93*90e502c7SAndroid Build Coastguard Worker printf("statistical tests driver\n");
94*90e502c7SAndroid Build Coastguard Worker
95*90e502c7SAndroid Build Coastguard Worker v128_set_to_zero(&nonce);
96*90e502c7SAndroid Build Coastguard Worker for (i = 0; i < 2500; i++)
97*90e502c7SAndroid Build Coastguard Worker buffer[i] = 0;
98*90e502c7SAndroid Build Coastguard Worker
99*90e502c7SAndroid Build Coastguard Worker /* run tests */
100*90e502c7SAndroid Build Coastguard Worker printf("running stat_tests on all-null buffer, expecting failure\n");
101*90e502c7SAndroid Build Coastguard Worker printf("monobit %d\n", stat_test_monobit(buffer));
102*90e502c7SAndroid Build Coastguard Worker printf("poker %d\n", stat_test_poker(buffer));
103*90e502c7SAndroid Build Coastguard Worker printf("runs %d\n", stat_test_runs(buffer));
104*90e502c7SAndroid Build Coastguard Worker
105*90e502c7SAndroid Build Coastguard Worker srtp_cipher_rand_for_tests(buffer, 2500);
106*90e502c7SAndroid Build Coastguard Worker printf("running stat_tests on rand(), expecting success\n");
107*90e502c7SAndroid Build Coastguard Worker printf("monobit %d\n", stat_test_monobit(buffer));
108*90e502c7SAndroid Build Coastguard Worker printf("poker %d\n", stat_test_poker(buffer));
109*90e502c7SAndroid Build Coastguard Worker printf("runs %d\n", stat_test_runs(buffer));
110*90e502c7SAndroid Build Coastguard Worker
111*90e502c7SAndroid Build Coastguard Worker printf("running stat_tests on AES-128-ICM, expecting success\n");
112*90e502c7SAndroid Build Coastguard Worker /* set buffer to cipher output */
113*90e502c7SAndroid Build Coastguard Worker for (i = 0; i < 2500; i++)
114*90e502c7SAndroid Build Coastguard Worker buffer[i] = 0;
115*90e502c7SAndroid Build Coastguard Worker err_check(srtp_cipher_type_alloc(&srtp_aes_icm_128, &c,
116*90e502c7SAndroid Build Coastguard Worker SRTP_AES_ICM_128_KEY_LEN_WSALT, 0));
117*90e502c7SAndroid Build Coastguard Worker err_check(srtp_cipher_init(c, key));
118*90e502c7SAndroid Build Coastguard Worker err_check(srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
119*90e502c7SAndroid Build Coastguard Worker err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
120*90e502c7SAndroid Build Coastguard Worker /* run tests on cipher outout */
121*90e502c7SAndroid Build Coastguard Worker printf("monobit %d\n", stat_test_monobit(buffer));
122*90e502c7SAndroid Build Coastguard Worker printf("poker %d\n", stat_test_poker(buffer));
123*90e502c7SAndroid Build Coastguard Worker printf("runs %d\n", stat_test_runs(buffer));
124*90e502c7SAndroid Build Coastguard Worker
125*90e502c7SAndroid Build Coastguard Worker printf("runs test (please be patient): ");
126*90e502c7SAndroid Build Coastguard Worker fflush(stdout);
127*90e502c7SAndroid Build Coastguard Worker num_fail = 0;
128*90e502c7SAndroid Build Coastguard Worker v128_set_to_zero(&nonce);
129*90e502c7SAndroid Build Coastguard Worker for (j = 0; j < num_trials; j++) {
130*90e502c7SAndroid Build Coastguard Worker for (i = 0; i < 2500; i++)
131*90e502c7SAndroid Build Coastguard Worker buffer[i] = 0;
132*90e502c7SAndroid Build Coastguard Worker nonce.v32[3] = i;
133*90e502c7SAndroid Build Coastguard Worker err_check(
134*90e502c7SAndroid Build Coastguard Worker srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
135*90e502c7SAndroid Build Coastguard Worker err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
136*90e502c7SAndroid Build Coastguard Worker if (stat_test_runs(buffer)) {
137*90e502c7SAndroid Build Coastguard Worker num_fail++;
138*90e502c7SAndroid Build Coastguard Worker }
139*90e502c7SAndroid Build Coastguard Worker }
140*90e502c7SAndroid Build Coastguard Worker
141*90e502c7SAndroid Build Coastguard Worker printf("%d failures in %d tests\n", num_fail, num_trials);
142*90e502c7SAndroid Build Coastguard Worker printf("(nota bene: a small fraction of stat_test failures does not \n"
143*90e502c7SAndroid Build Coastguard Worker "indicate that the random source is invalid)\n");
144*90e502c7SAndroid Build Coastguard Worker
145*90e502c7SAndroid Build Coastguard Worker err_check(srtp_cipher_dealloc(c));
146*90e502c7SAndroid Build Coastguard Worker
147*90e502c7SAndroid Build Coastguard Worker printf("running stat_tests on AES-256-ICM, expecting success\n");
148*90e502c7SAndroid Build Coastguard Worker /* set buffer to cipher output */
149*90e502c7SAndroid Build Coastguard Worker for (i = 0; i < 2500; i++)
150*90e502c7SAndroid Build Coastguard Worker buffer[i] = 0;
151*90e502c7SAndroid Build Coastguard Worker err_check(srtp_cipher_type_alloc(&srtp_aes_icm_256, &c,
152*90e502c7SAndroid Build Coastguard Worker SRTP_AES_ICM_256_KEY_LEN_WSALT, 0));
153*90e502c7SAndroid Build Coastguard Worker err_check(srtp_cipher_init(c, key));
154*90e502c7SAndroid Build Coastguard Worker err_check(srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
155*90e502c7SAndroid Build Coastguard Worker err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
156*90e502c7SAndroid Build Coastguard Worker /* run tests on cipher outout */
157*90e502c7SAndroid Build Coastguard Worker printf("monobit %d\n", stat_test_monobit(buffer));
158*90e502c7SAndroid Build Coastguard Worker printf("poker %d\n", stat_test_poker(buffer));
159*90e502c7SAndroid Build Coastguard Worker printf("runs %d\n", stat_test_runs(buffer));
160*90e502c7SAndroid Build Coastguard Worker
161*90e502c7SAndroid Build Coastguard Worker printf("runs test (please be patient): ");
162*90e502c7SAndroid Build Coastguard Worker fflush(stdout);
163*90e502c7SAndroid Build Coastguard Worker num_fail = 0;
164*90e502c7SAndroid Build Coastguard Worker v128_set_to_zero(&nonce);
165*90e502c7SAndroid Build Coastguard Worker for (j = 0; j < num_trials; j++) {
166*90e502c7SAndroid Build Coastguard Worker for (i = 0; i < 2500; i++)
167*90e502c7SAndroid Build Coastguard Worker buffer[i] = 0;
168*90e502c7SAndroid Build Coastguard Worker nonce.v32[3] = i;
169*90e502c7SAndroid Build Coastguard Worker err_check(
170*90e502c7SAndroid Build Coastguard Worker srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
171*90e502c7SAndroid Build Coastguard Worker err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
172*90e502c7SAndroid Build Coastguard Worker if (stat_test_runs(buffer)) {
173*90e502c7SAndroid Build Coastguard Worker num_fail++;
174*90e502c7SAndroid Build Coastguard Worker }
175*90e502c7SAndroid Build Coastguard Worker }
176*90e502c7SAndroid Build Coastguard Worker
177*90e502c7SAndroid Build Coastguard Worker #ifdef GCM
178*90e502c7SAndroid Build Coastguard Worker {
179*90e502c7SAndroid Build Coastguard Worker printf("running stat_tests on AES-128-GCM, expecting success\n");
180*90e502c7SAndroid Build Coastguard Worker /* set buffer to cipher output */
181*90e502c7SAndroid Build Coastguard Worker for (i = 0; i < 2500; i++) {
182*90e502c7SAndroid Build Coastguard Worker buffer[i] = 0;
183*90e502c7SAndroid Build Coastguard Worker }
184*90e502c7SAndroid Build Coastguard Worker err_check(srtp_cipher_type_alloc(&srtp_aes_gcm_128, &c,
185*90e502c7SAndroid Build Coastguard Worker SRTP_AES_GCM_128_KEY_LEN_WSALT, 8));
186*90e502c7SAndroid Build Coastguard Worker err_check(srtp_cipher_init(c, key));
187*90e502c7SAndroid Build Coastguard Worker err_check(
188*90e502c7SAndroid Build Coastguard Worker srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
189*90e502c7SAndroid Build Coastguard Worker err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
190*90e502c7SAndroid Build Coastguard Worker /* run tests on cipher outout */
191*90e502c7SAndroid Build Coastguard Worker printf("monobit %d\n", stat_test_monobit(buffer));
192*90e502c7SAndroid Build Coastguard Worker printf("poker %d\n", stat_test_poker(buffer));
193*90e502c7SAndroid Build Coastguard Worker printf("runs %d\n", stat_test_runs(buffer));
194*90e502c7SAndroid Build Coastguard Worker fflush(stdout);
195*90e502c7SAndroid Build Coastguard Worker num_fail = 0;
196*90e502c7SAndroid Build Coastguard Worker v128_set_to_zero(&nonce);
197*90e502c7SAndroid Build Coastguard Worker for (j = 0; j < num_trials; j++) {
198*90e502c7SAndroid Build Coastguard Worker for (i = 0; i < 2500; i++) {
199*90e502c7SAndroid Build Coastguard Worker buffer[i] = 0;
200*90e502c7SAndroid Build Coastguard Worker }
201*90e502c7SAndroid Build Coastguard Worker nonce.v32[3] = i;
202*90e502c7SAndroid Build Coastguard Worker err_check(srtp_cipher_set_iv(c, (uint8_t *)&nonce,
203*90e502c7SAndroid Build Coastguard Worker srtp_direction_encrypt));
204*90e502c7SAndroid Build Coastguard Worker err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
205*90e502c7SAndroid Build Coastguard Worker buf_len = 2500;
206*90e502c7SAndroid Build Coastguard Worker if (stat_test_runs(buffer)) {
207*90e502c7SAndroid Build Coastguard Worker num_fail++;
208*90e502c7SAndroid Build Coastguard Worker }
209*90e502c7SAndroid Build Coastguard Worker }
210*90e502c7SAndroid Build Coastguard Worker
211*90e502c7SAndroid Build Coastguard Worker printf("running stat_tests on AES-256-GCM, expecting success\n");
212*90e502c7SAndroid Build Coastguard Worker /* set buffer to cipher output */
213*90e502c7SAndroid Build Coastguard Worker for (i = 0; i < 2500; i++) {
214*90e502c7SAndroid Build Coastguard Worker buffer[i] = 0;
215*90e502c7SAndroid Build Coastguard Worker }
216*90e502c7SAndroid Build Coastguard Worker err_check(srtp_cipher_type_alloc(&srtp_aes_gcm_256, &c,
217*90e502c7SAndroid Build Coastguard Worker SRTP_AES_GCM_256_KEY_LEN_WSALT, 16));
218*90e502c7SAndroid Build Coastguard Worker err_check(srtp_cipher_init(c, key));
219*90e502c7SAndroid Build Coastguard Worker err_check(
220*90e502c7SAndroid Build Coastguard Worker srtp_cipher_set_iv(c, (uint8_t *)&nonce, srtp_direction_encrypt));
221*90e502c7SAndroid Build Coastguard Worker err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
222*90e502c7SAndroid Build Coastguard Worker /* run tests on cipher outout */
223*90e502c7SAndroid Build Coastguard Worker printf("monobit %d\n", stat_test_monobit(buffer));
224*90e502c7SAndroid Build Coastguard Worker printf("poker %d\n", stat_test_poker(buffer));
225*90e502c7SAndroid Build Coastguard Worker printf("runs %d\n", stat_test_runs(buffer));
226*90e502c7SAndroid Build Coastguard Worker fflush(stdout);
227*90e502c7SAndroid Build Coastguard Worker num_fail = 0;
228*90e502c7SAndroid Build Coastguard Worker v128_set_to_zero(&nonce);
229*90e502c7SAndroid Build Coastguard Worker for (j = 0; j < num_trials; j++) {
230*90e502c7SAndroid Build Coastguard Worker for (i = 0; i < 2500; i++) {
231*90e502c7SAndroid Build Coastguard Worker buffer[i] = 0;
232*90e502c7SAndroid Build Coastguard Worker }
233*90e502c7SAndroid Build Coastguard Worker nonce.v32[3] = i;
234*90e502c7SAndroid Build Coastguard Worker err_check(srtp_cipher_set_iv(c, (uint8_t *)&nonce,
235*90e502c7SAndroid Build Coastguard Worker srtp_direction_encrypt));
236*90e502c7SAndroid Build Coastguard Worker err_check(srtp_cipher_encrypt(c, buffer, &buf_len));
237*90e502c7SAndroid Build Coastguard Worker buf_len = 2500;
238*90e502c7SAndroid Build Coastguard Worker if (stat_test_runs(buffer)) {
239*90e502c7SAndroid Build Coastguard Worker num_fail++;
240*90e502c7SAndroid Build Coastguard Worker }
241*90e502c7SAndroid Build Coastguard Worker }
242*90e502c7SAndroid Build Coastguard Worker }
243*90e502c7SAndroid Build Coastguard Worker #endif
244*90e502c7SAndroid Build Coastguard Worker
245*90e502c7SAndroid Build Coastguard Worker printf("%d failures in %d tests\n", num_fail, num_trials);
246*90e502c7SAndroid Build Coastguard Worker printf("(nota bene: a small fraction of stat_test failures does not \n"
247*90e502c7SAndroid Build Coastguard Worker "indicate that the random source is invalid)\n");
248*90e502c7SAndroid Build Coastguard Worker
249*90e502c7SAndroid Build Coastguard Worker err_check(srtp_cipher_dealloc(c));
250*90e502c7SAndroid Build Coastguard Worker
251*90e502c7SAndroid Build Coastguard Worker return 0;
252*90e502c7SAndroid Build Coastguard Worker }
253