1*90e502c7SAndroid Build Coastguard Worker /*
2*90e502c7SAndroid Build Coastguard Worker * cipher_driver.c
3*90e502c7SAndroid Build Coastguard Worker *
4*90e502c7SAndroid Build Coastguard Worker * A driver for the generic cipher type
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 #include "getopt_s.h"
52*90e502c7SAndroid Build Coastguard Worker #include "cipher.h"
53*90e502c7SAndroid Build Coastguard Worker #include "cipher_priv.h"
54*90e502c7SAndroid Build Coastguard Worker #ifdef GCM
55*90e502c7SAndroid Build Coastguard Worker #include "aes_icm_ext.h"
56*90e502c7SAndroid Build Coastguard Worker #include "aes_gcm.h"
57*90e502c7SAndroid Build Coastguard Worker #else
58*90e502c7SAndroid Build Coastguard Worker #include "aes_icm.h"
59*90e502c7SAndroid Build Coastguard Worker #endif
60*90e502c7SAndroid Build Coastguard Worker
61*90e502c7SAndroid Build Coastguard Worker #define PRINT_DEBUG 0
62*90e502c7SAndroid Build Coastguard Worker
63*90e502c7SAndroid Build Coastguard Worker void cipher_driver_test_throughput(srtp_cipher_t *c);
64*90e502c7SAndroid Build Coastguard Worker
65*90e502c7SAndroid Build Coastguard Worker srtp_err_status_t cipher_driver_self_test(srtp_cipher_type_t *ct);
66*90e502c7SAndroid Build Coastguard Worker
67*90e502c7SAndroid Build Coastguard Worker /*
68*90e502c7SAndroid Build Coastguard Worker * cipher_driver_test_buffering(ct) tests the cipher's output
69*90e502c7SAndroid Build Coastguard Worker * buffering for correctness by checking the consistency of succesive
70*90e502c7SAndroid Build Coastguard Worker * calls
71*90e502c7SAndroid Build Coastguard Worker */
72*90e502c7SAndroid Build Coastguard Worker
73*90e502c7SAndroid Build Coastguard Worker srtp_err_status_t cipher_driver_test_buffering(srtp_cipher_t *c);
74*90e502c7SAndroid Build Coastguard Worker
75*90e502c7SAndroid Build Coastguard Worker /*
76*90e502c7SAndroid Build Coastguard Worker * functions for testing cipher cache thrash
77*90e502c7SAndroid Build Coastguard Worker */
78*90e502c7SAndroid Build Coastguard Worker srtp_err_status_t cipher_driver_test_array_throughput(srtp_cipher_type_t *ct,
79*90e502c7SAndroid Build Coastguard Worker int klen,
80*90e502c7SAndroid Build Coastguard Worker int num_cipher);
81*90e502c7SAndroid Build Coastguard Worker
82*90e502c7SAndroid Build Coastguard Worker void cipher_array_test_throughput(srtp_cipher_t *ca[], int num_cipher);
83*90e502c7SAndroid Build Coastguard Worker
84*90e502c7SAndroid Build Coastguard Worker uint64_t cipher_array_bits_per_second(srtp_cipher_t *cipher_array[],
85*90e502c7SAndroid Build Coastguard Worker int num_cipher,
86*90e502c7SAndroid Build Coastguard Worker unsigned octets_in_buffer,
87*90e502c7SAndroid Build Coastguard Worker int num_trials);
88*90e502c7SAndroid Build Coastguard Worker
89*90e502c7SAndroid Build Coastguard Worker srtp_err_status_t cipher_array_delete(srtp_cipher_t *cipher_array[],
90*90e502c7SAndroid Build Coastguard Worker int num_cipher);
91*90e502c7SAndroid Build Coastguard Worker
92*90e502c7SAndroid Build Coastguard Worker srtp_err_status_t cipher_array_alloc_init(srtp_cipher_t ***cipher_array,
93*90e502c7SAndroid Build Coastguard Worker int num_ciphers,
94*90e502c7SAndroid Build Coastguard Worker srtp_cipher_type_t *ctype,
95*90e502c7SAndroid Build Coastguard Worker int klen);
96*90e502c7SAndroid Build Coastguard Worker
usage(char * prog_name)97*90e502c7SAndroid Build Coastguard Worker void usage(char *prog_name)
98*90e502c7SAndroid Build Coastguard Worker {
99*90e502c7SAndroid Build Coastguard Worker printf("usage: %s [ -t | -v | -a ]\n", prog_name);
100*90e502c7SAndroid Build Coastguard Worker exit(255);
101*90e502c7SAndroid Build Coastguard Worker }
102*90e502c7SAndroid Build Coastguard Worker
check_status(srtp_err_status_t s)103*90e502c7SAndroid Build Coastguard Worker void check_status(srtp_err_status_t s)
104*90e502c7SAndroid Build Coastguard Worker {
105*90e502c7SAndroid Build Coastguard Worker if (s) {
106*90e502c7SAndroid Build Coastguard Worker printf("error (code %d)\n", s);
107*90e502c7SAndroid Build Coastguard Worker exit(s);
108*90e502c7SAndroid Build Coastguard Worker }
109*90e502c7SAndroid Build Coastguard Worker return;
110*90e502c7SAndroid Build Coastguard Worker }
111*90e502c7SAndroid Build Coastguard Worker
112*90e502c7SAndroid Build Coastguard Worker /*
113*90e502c7SAndroid Build Coastguard Worker * null_cipher and srtp_aes_icm are the cipher meta-objects
114*90e502c7SAndroid Build Coastguard Worker * defined in the files in crypto/cipher subdirectory. these are
115*90e502c7SAndroid Build Coastguard Worker * declared external so that we can use these cipher types here
116*90e502c7SAndroid Build Coastguard Worker */
117*90e502c7SAndroid Build Coastguard Worker
118*90e502c7SAndroid Build Coastguard Worker extern srtp_cipher_type_t srtp_null_cipher;
119*90e502c7SAndroid Build Coastguard Worker extern srtp_cipher_type_t srtp_aes_icm_128;
120*90e502c7SAndroid Build Coastguard Worker extern srtp_cipher_type_t srtp_aes_icm_256;
121*90e502c7SAndroid Build Coastguard Worker #ifdef GCM
122*90e502c7SAndroid Build Coastguard Worker extern srtp_cipher_type_t srtp_aes_icm_192;
123*90e502c7SAndroid Build Coastguard Worker extern srtp_cipher_type_t srtp_aes_gcm_128;
124*90e502c7SAndroid Build Coastguard Worker extern srtp_cipher_type_t srtp_aes_gcm_256;
125*90e502c7SAndroid Build Coastguard Worker #endif
126*90e502c7SAndroid Build Coastguard Worker
main(int argc,char * argv[])127*90e502c7SAndroid Build Coastguard Worker int main(int argc, char *argv[])
128*90e502c7SAndroid Build Coastguard Worker {
129*90e502c7SAndroid Build Coastguard Worker srtp_cipher_t *c = NULL;
130*90e502c7SAndroid Build Coastguard Worker srtp_err_status_t status;
131*90e502c7SAndroid Build Coastguard Worker /* clang-format off */
132*90e502c7SAndroid Build Coastguard Worker unsigned char test_key[48] = {
133*90e502c7SAndroid Build Coastguard Worker 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
134*90e502c7SAndroid Build Coastguard Worker 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
135*90e502c7SAndroid Build Coastguard Worker 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
136*90e502c7SAndroid Build Coastguard Worker 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
137*90e502c7SAndroid Build Coastguard Worker 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
138*90e502c7SAndroid Build Coastguard Worker 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
139*90e502c7SAndroid Build Coastguard Worker };
140*90e502c7SAndroid Build Coastguard Worker /* clang-format on */
141*90e502c7SAndroid Build Coastguard Worker int q;
142*90e502c7SAndroid Build Coastguard Worker unsigned do_timing_test = 0;
143*90e502c7SAndroid Build Coastguard Worker unsigned do_validation = 0;
144*90e502c7SAndroid Build Coastguard Worker unsigned do_array_timing_test = 0;
145*90e502c7SAndroid Build Coastguard Worker
146*90e502c7SAndroid Build Coastguard Worker /* process input arguments */
147*90e502c7SAndroid Build Coastguard Worker while (1) {
148*90e502c7SAndroid Build Coastguard Worker q = getopt_s(argc, argv, "tva");
149*90e502c7SAndroid Build Coastguard Worker if (q == -1)
150*90e502c7SAndroid Build Coastguard Worker break;
151*90e502c7SAndroid Build Coastguard Worker switch (q) {
152*90e502c7SAndroid Build Coastguard Worker case 't':
153*90e502c7SAndroid Build Coastguard Worker do_timing_test = 1;
154*90e502c7SAndroid Build Coastguard Worker break;
155*90e502c7SAndroid Build Coastguard Worker case 'v':
156*90e502c7SAndroid Build Coastguard Worker do_validation = 1;
157*90e502c7SAndroid Build Coastguard Worker break;
158*90e502c7SAndroid Build Coastguard Worker case 'a':
159*90e502c7SAndroid Build Coastguard Worker do_array_timing_test = 1;
160*90e502c7SAndroid Build Coastguard Worker break;
161*90e502c7SAndroid Build Coastguard Worker default:
162*90e502c7SAndroid Build Coastguard Worker usage(argv[0]);
163*90e502c7SAndroid Build Coastguard Worker }
164*90e502c7SAndroid Build Coastguard Worker }
165*90e502c7SAndroid Build Coastguard Worker
166*90e502c7SAndroid Build Coastguard Worker printf("cipher test driver\n"
167*90e502c7SAndroid Build Coastguard Worker "David A. McGrew\n"
168*90e502c7SAndroid Build Coastguard Worker "Cisco Systems, Inc.\n");
169*90e502c7SAndroid Build Coastguard Worker
170*90e502c7SAndroid Build Coastguard Worker if (!do_validation && !do_timing_test && !do_array_timing_test)
171*90e502c7SAndroid Build Coastguard Worker usage(argv[0]);
172*90e502c7SAndroid Build Coastguard Worker
173*90e502c7SAndroid Build Coastguard Worker /* arry timing (cache thrash) test */
174*90e502c7SAndroid Build Coastguard Worker if (do_array_timing_test) {
175*90e502c7SAndroid Build Coastguard Worker int max_num_cipher = 1 << 16; /* number of ciphers in cipher_array */
176*90e502c7SAndroid Build Coastguard Worker int num_cipher;
177*90e502c7SAndroid Build Coastguard Worker
178*90e502c7SAndroid Build Coastguard Worker for (num_cipher = 1; num_cipher < max_num_cipher; num_cipher *= 8)
179*90e502c7SAndroid Build Coastguard Worker cipher_driver_test_array_throughput(&srtp_null_cipher, 0,
180*90e502c7SAndroid Build Coastguard Worker num_cipher);
181*90e502c7SAndroid Build Coastguard Worker
182*90e502c7SAndroid Build Coastguard Worker for (num_cipher = 1; num_cipher < max_num_cipher; num_cipher *= 8)
183*90e502c7SAndroid Build Coastguard Worker cipher_driver_test_array_throughput(
184*90e502c7SAndroid Build Coastguard Worker &srtp_aes_icm_128, SRTP_AES_ICM_128_KEY_LEN_WSALT, num_cipher);
185*90e502c7SAndroid Build Coastguard Worker
186*90e502c7SAndroid Build Coastguard Worker for (num_cipher = 1; num_cipher < max_num_cipher; num_cipher *= 8)
187*90e502c7SAndroid Build Coastguard Worker cipher_driver_test_array_throughput(
188*90e502c7SAndroid Build Coastguard Worker &srtp_aes_icm_256, SRTP_AES_ICM_256_KEY_LEN_WSALT, num_cipher);
189*90e502c7SAndroid Build Coastguard Worker
190*90e502c7SAndroid Build Coastguard Worker #ifdef GCM
191*90e502c7SAndroid Build Coastguard Worker for (num_cipher = 1; num_cipher < max_num_cipher; num_cipher *= 8)
192*90e502c7SAndroid Build Coastguard Worker cipher_driver_test_array_throughput(
193*90e502c7SAndroid Build Coastguard Worker &srtp_aes_icm_192, SRTP_AES_ICM_192_KEY_LEN_WSALT, num_cipher);
194*90e502c7SAndroid Build Coastguard Worker
195*90e502c7SAndroid Build Coastguard Worker for (num_cipher = 1; num_cipher < max_num_cipher; num_cipher *= 8) {
196*90e502c7SAndroid Build Coastguard Worker cipher_driver_test_array_throughput(
197*90e502c7SAndroid Build Coastguard Worker &srtp_aes_gcm_128, SRTP_AES_GCM_128_KEY_LEN_WSALT, num_cipher);
198*90e502c7SAndroid Build Coastguard Worker }
199*90e502c7SAndroid Build Coastguard Worker
200*90e502c7SAndroid Build Coastguard Worker for (num_cipher = 1; num_cipher < max_num_cipher; num_cipher *= 8) {
201*90e502c7SAndroid Build Coastguard Worker cipher_driver_test_array_throughput(
202*90e502c7SAndroid Build Coastguard Worker &srtp_aes_gcm_256, SRTP_AES_GCM_256_KEY_LEN_WSALT, num_cipher);
203*90e502c7SAndroid Build Coastguard Worker }
204*90e502c7SAndroid Build Coastguard Worker #endif
205*90e502c7SAndroid Build Coastguard Worker }
206*90e502c7SAndroid Build Coastguard Worker
207*90e502c7SAndroid Build Coastguard Worker if (do_validation) {
208*90e502c7SAndroid Build Coastguard Worker cipher_driver_self_test(&srtp_null_cipher);
209*90e502c7SAndroid Build Coastguard Worker cipher_driver_self_test(&srtp_aes_icm_128);
210*90e502c7SAndroid Build Coastguard Worker cipher_driver_self_test(&srtp_aes_icm_256);
211*90e502c7SAndroid Build Coastguard Worker #ifdef GCM
212*90e502c7SAndroid Build Coastguard Worker cipher_driver_self_test(&srtp_aes_icm_192);
213*90e502c7SAndroid Build Coastguard Worker cipher_driver_self_test(&srtp_aes_gcm_128);
214*90e502c7SAndroid Build Coastguard Worker cipher_driver_self_test(&srtp_aes_gcm_256);
215*90e502c7SAndroid Build Coastguard Worker #endif
216*90e502c7SAndroid Build Coastguard Worker }
217*90e502c7SAndroid Build Coastguard Worker
218*90e502c7SAndroid Build Coastguard Worker /* do timing and/or buffer_test on srtp_null_cipher */
219*90e502c7SAndroid Build Coastguard Worker status = srtp_cipher_type_alloc(&srtp_null_cipher, &c, 0, 0);
220*90e502c7SAndroid Build Coastguard Worker check_status(status);
221*90e502c7SAndroid Build Coastguard Worker
222*90e502c7SAndroid Build Coastguard Worker status = srtp_cipher_init(c, NULL);
223*90e502c7SAndroid Build Coastguard Worker check_status(status);
224*90e502c7SAndroid Build Coastguard Worker
225*90e502c7SAndroid Build Coastguard Worker if (do_timing_test)
226*90e502c7SAndroid Build Coastguard Worker cipher_driver_test_throughput(c);
227*90e502c7SAndroid Build Coastguard Worker if (do_validation) {
228*90e502c7SAndroid Build Coastguard Worker status = cipher_driver_test_buffering(c);
229*90e502c7SAndroid Build Coastguard Worker check_status(status);
230*90e502c7SAndroid Build Coastguard Worker }
231*90e502c7SAndroid Build Coastguard Worker status = srtp_cipher_dealloc(c);
232*90e502c7SAndroid Build Coastguard Worker check_status(status);
233*90e502c7SAndroid Build Coastguard Worker
234*90e502c7SAndroid Build Coastguard Worker /* run the throughput test on the aes_icm cipher (128-bit key) */
235*90e502c7SAndroid Build Coastguard Worker status = srtp_cipher_type_alloc(&srtp_aes_icm_128, &c,
236*90e502c7SAndroid Build Coastguard Worker SRTP_AES_ICM_128_KEY_LEN_WSALT, 0);
237*90e502c7SAndroid Build Coastguard Worker if (status) {
238*90e502c7SAndroid Build Coastguard Worker fprintf(stderr, "error: can't allocate cipher\n");
239*90e502c7SAndroid Build Coastguard Worker exit(status);
240*90e502c7SAndroid Build Coastguard Worker }
241*90e502c7SAndroid Build Coastguard Worker
242*90e502c7SAndroid Build Coastguard Worker status = srtp_cipher_init(c, test_key);
243*90e502c7SAndroid Build Coastguard Worker check_status(status);
244*90e502c7SAndroid Build Coastguard Worker
245*90e502c7SAndroid Build Coastguard Worker if (do_timing_test)
246*90e502c7SAndroid Build Coastguard Worker cipher_driver_test_throughput(c);
247*90e502c7SAndroid Build Coastguard Worker
248*90e502c7SAndroid Build Coastguard Worker if (do_validation) {
249*90e502c7SAndroid Build Coastguard Worker status = cipher_driver_test_buffering(c);
250*90e502c7SAndroid Build Coastguard Worker check_status(status);
251*90e502c7SAndroid Build Coastguard Worker }
252*90e502c7SAndroid Build Coastguard Worker
253*90e502c7SAndroid Build Coastguard Worker status = srtp_cipher_dealloc(c);
254*90e502c7SAndroid Build Coastguard Worker check_status(status);
255*90e502c7SAndroid Build Coastguard Worker
256*90e502c7SAndroid Build Coastguard Worker /* repeat the tests with 256-bit keys */
257*90e502c7SAndroid Build Coastguard Worker status = srtp_cipher_type_alloc(&srtp_aes_icm_256, &c,
258*90e502c7SAndroid Build Coastguard Worker SRTP_AES_ICM_256_KEY_LEN_WSALT, 0);
259*90e502c7SAndroid Build Coastguard Worker if (status) {
260*90e502c7SAndroid Build Coastguard Worker fprintf(stderr, "error: can't allocate cipher\n");
261*90e502c7SAndroid Build Coastguard Worker exit(status);
262*90e502c7SAndroid Build Coastguard Worker }
263*90e502c7SAndroid Build Coastguard Worker
264*90e502c7SAndroid Build Coastguard Worker status = srtp_cipher_init(c, test_key);
265*90e502c7SAndroid Build Coastguard Worker check_status(status);
266*90e502c7SAndroid Build Coastguard Worker
267*90e502c7SAndroid Build Coastguard Worker if (do_timing_test)
268*90e502c7SAndroid Build Coastguard Worker cipher_driver_test_throughput(c);
269*90e502c7SAndroid Build Coastguard Worker
270*90e502c7SAndroid Build Coastguard Worker if (do_validation) {
271*90e502c7SAndroid Build Coastguard Worker status = cipher_driver_test_buffering(c);
272*90e502c7SAndroid Build Coastguard Worker check_status(status);
273*90e502c7SAndroid Build Coastguard Worker }
274*90e502c7SAndroid Build Coastguard Worker
275*90e502c7SAndroid Build Coastguard Worker status = srtp_cipher_dealloc(c);
276*90e502c7SAndroid Build Coastguard Worker check_status(status);
277*90e502c7SAndroid Build Coastguard Worker
278*90e502c7SAndroid Build Coastguard Worker #ifdef GCM
279*90e502c7SAndroid Build Coastguard Worker /* run the throughput test on the aes_gcm_128 cipher */
280*90e502c7SAndroid Build Coastguard Worker status = srtp_cipher_type_alloc(&srtp_aes_gcm_128, &c,
281*90e502c7SAndroid Build Coastguard Worker SRTP_AES_GCM_128_KEY_LEN_WSALT, 8);
282*90e502c7SAndroid Build Coastguard Worker if (status) {
283*90e502c7SAndroid Build Coastguard Worker fprintf(stderr, "error: can't allocate GCM 128 cipher\n");
284*90e502c7SAndroid Build Coastguard Worker exit(status);
285*90e502c7SAndroid Build Coastguard Worker }
286*90e502c7SAndroid Build Coastguard Worker status = srtp_cipher_init(c, test_key);
287*90e502c7SAndroid Build Coastguard Worker check_status(status);
288*90e502c7SAndroid Build Coastguard Worker if (do_timing_test) {
289*90e502c7SAndroid Build Coastguard Worker cipher_driver_test_throughput(c);
290*90e502c7SAndroid Build Coastguard Worker }
291*90e502c7SAndroid Build Coastguard Worker
292*90e502c7SAndroid Build Coastguard Worker // GCM ciphers don't do buffering; they're "one shot"
293*90e502c7SAndroid Build Coastguard Worker
294*90e502c7SAndroid Build Coastguard Worker status = srtp_cipher_dealloc(c);
295*90e502c7SAndroid Build Coastguard Worker check_status(status);
296*90e502c7SAndroid Build Coastguard Worker
297*90e502c7SAndroid Build Coastguard Worker /* run the throughput test on the aes_gcm_256 cipher */
298*90e502c7SAndroid Build Coastguard Worker status = srtp_cipher_type_alloc(&srtp_aes_gcm_256, &c,
299*90e502c7SAndroid Build Coastguard Worker SRTP_AES_GCM_256_KEY_LEN_WSALT, 16);
300*90e502c7SAndroid Build Coastguard Worker if (status) {
301*90e502c7SAndroid Build Coastguard Worker fprintf(stderr, "error: can't allocate GCM 256 cipher\n");
302*90e502c7SAndroid Build Coastguard Worker exit(status);
303*90e502c7SAndroid Build Coastguard Worker }
304*90e502c7SAndroid Build Coastguard Worker status = srtp_cipher_init(c, test_key);
305*90e502c7SAndroid Build Coastguard Worker check_status(status);
306*90e502c7SAndroid Build Coastguard Worker if (do_timing_test) {
307*90e502c7SAndroid Build Coastguard Worker cipher_driver_test_throughput(c);
308*90e502c7SAndroid Build Coastguard Worker }
309*90e502c7SAndroid Build Coastguard Worker
310*90e502c7SAndroid Build Coastguard Worker // GCM ciphers don't do buffering; they're "one shot"
311*90e502c7SAndroid Build Coastguard Worker
312*90e502c7SAndroid Build Coastguard Worker status = srtp_cipher_dealloc(c);
313*90e502c7SAndroid Build Coastguard Worker check_status(status);
314*90e502c7SAndroid Build Coastguard Worker #endif
315*90e502c7SAndroid Build Coastguard Worker
316*90e502c7SAndroid Build Coastguard Worker return 0;
317*90e502c7SAndroid Build Coastguard Worker }
318*90e502c7SAndroid Build Coastguard Worker
cipher_driver_test_throughput(srtp_cipher_t * c)319*90e502c7SAndroid Build Coastguard Worker void cipher_driver_test_throughput(srtp_cipher_t *c)
320*90e502c7SAndroid Build Coastguard Worker {
321*90e502c7SAndroid Build Coastguard Worker int i;
322*90e502c7SAndroid Build Coastguard Worker int min_enc_len = 32;
323*90e502c7SAndroid Build Coastguard Worker int max_enc_len = 2048; /* should be a power of two */
324*90e502c7SAndroid Build Coastguard Worker int num_trials = 1000000;
325*90e502c7SAndroid Build Coastguard Worker
326*90e502c7SAndroid Build Coastguard Worker printf("timing %s throughput, key length %d:\n", c->type->description,
327*90e502c7SAndroid Build Coastguard Worker c->key_len);
328*90e502c7SAndroid Build Coastguard Worker fflush(stdout);
329*90e502c7SAndroid Build Coastguard Worker for (i = min_enc_len; i <= max_enc_len; i = i * 2)
330*90e502c7SAndroid Build Coastguard Worker printf("msg len: %d\tgigabits per second: %f\n", i,
331*90e502c7SAndroid Build Coastguard Worker srtp_cipher_bits_per_second(c, i, num_trials) / 1e9);
332*90e502c7SAndroid Build Coastguard Worker }
333*90e502c7SAndroid Build Coastguard Worker
cipher_driver_self_test(srtp_cipher_type_t * ct)334*90e502c7SAndroid Build Coastguard Worker srtp_err_status_t cipher_driver_self_test(srtp_cipher_type_t *ct)
335*90e502c7SAndroid Build Coastguard Worker {
336*90e502c7SAndroid Build Coastguard Worker srtp_err_status_t status;
337*90e502c7SAndroid Build Coastguard Worker
338*90e502c7SAndroid Build Coastguard Worker printf("running cipher self-test for %s...", ct->description);
339*90e502c7SAndroid Build Coastguard Worker status = srtp_cipher_type_self_test(ct);
340*90e502c7SAndroid Build Coastguard Worker if (status) {
341*90e502c7SAndroid Build Coastguard Worker printf("failed with error code %d\n", status);
342*90e502c7SAndroid Build Coastguard Worker exit(status);
343*90e502c7SAndroid Build Coastguard Worker }
344*90e502c7SAndroid Build Coastguard Worker printf("passed\n");
345*90e502c7SAndroid Build Coastguard Worker
346*90e502c7SAndroid Build Coastguard Worker return srtp_err_status_ok;
347*90e502c7SAndroid Build Coastguard Worker }
348*90e502c7SAndroid Build Coastguard Worker
349*90e502c7SAndroid Build Coastguard Worker /*
350*90e502c7SAndroid Build Coastguard Worker * cipher_driver_test_buffering(ct) tests the cipher's output
351*90e502c7SAndroid Build Coastguard Worker * buffering for correctness by checking the consistency of succesive
352*90e502c7SAndroid Build Coastguard Worker * calls
353*90e502c7SAndroid Build Coastguard Worker */
354*90e502c7SAndroid Build Coastguard Worker
355*90e502c7SAndroid Build Coastguard Worker #define INITIAL_BUFLEN 1024
cipher_driver_test_buffering(srtp_cipher_t * c)356*90e502c7SAndroid Build Coastguard Worker srtp_err_status_t cipher_driver_test_buffering(srtp_cipher_t *c)
357*90e502c7SAndroid Build Coastguard Worker {
358*90e502c7SAndroid Build Coastguard Worker int i, j, num_trials = 1000;
359*90e502c7SAndroid Build Coastguard Worker unsigned len, buflen = INITIAL_BUFLEN;
360*90e502c7SAndroid Build Coastguard Worker uint8_t buffer0[INITIAL_BUFLEN], buffer1[INITIAL_BUFLEN], *current, *end;
361*90e502c7SAndroid Build Coastguard Worker uint8_t idx[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362*90e502c7SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34 };
363*90e502c7SAndroid Build Coastguard Worker srtp_err_status_t status;
364*90e502c7SAndroid Build Coastguard Worker
365*90e502c7SAndroid Build Coastguard Worker printf("testing output buffering for cipher %s...", c->type->description);
366*90e502c7SAndroid Build Coastguard Worker
367*90e502c7SAndroid Build Coastguard Worker for (i = 0; i < num_trials; i++) {
368*90e502c7SAndroid Build Coastguard Worker /* set buffers to zero */
369*90e502c7SAndroid Build Coastguard Worker for (j = 0; j < (int)buflen; j++) {
370*90e502c7SAndroid Build Coastguard Worker buffer0[j] = buffer1[j] = 0;
371*90e502c7SAndroid Build Coastguard Worker }
372*90e502c7SAndroid Build Coastguard Worker
373*90e502c7SAndroid Build Coastguard Worker /* initialize cipher */
374*90e502c7SAndroid Build Coastguard Worker status = srtp_cipher_set_iv(c, (uint8_t *)idx, srtp_direction_encrypt);
375*90e502c7SAndroid Build Coastguard Worker if (status)
376*90e502c7SAndroid Build Coastguard Worker return status;
377*90e502c7SAndroid Build Coastguard Worker
378*90e502c7SAndroid Build Coastguard Worker /* generate 'reference' value by encrypting all at once */
379*90e502c7SAndroid Build Coastguard Worker status = srtp_cipher_encrypt(c, buffer0, &buflen);
380*90e502c7SAndroid Build Coastguard Worker if (status)
381*90e502c7SAndroid Build Coastguard Worker return status;
382*90e502c7SAndroid Build Coastguard Worker
383*90e502c7SAndroid Build Coastguard Worker /* re-initialize cipher */
384*90e502c7SAndroid Build Coastguard Worker status = srtp_cipher_set_iv(c, (uint8_t *)idx, srtp_direction_encrypt);
385*90e502c7SAndroid Build Coastguard Worker if (status)
386*90e502c7SAndroid Build Coastguard Worker return status;
387*90e502c7SAndroid Build Coastguard Worker
388*90e502c7SAndroid Build Coastguard Worker /* now loop over short lengths until buffer1 is encrypted */
389*90e502c7SAndroid Build Coastguard Worker current = buffer1;
390*90e502c7SAndroid Build Coastguard Worker end = buffer1 + buflen;
391*90e502c7SAndroid Build Coastguard Worker while (current < end) {
392*90e502c7SAndroid Build Coastguard Worker /* choose a short length */
393*90e502c7SAndroid Build Coastguard Worker len = srtp_cipher_rand_u32_for_tests() & 0x01f;
394*90e502c7SAndroid Build Coastguard Worker
395*90e502c7SAndroid Build Coastguard Worker /* make sure that len doesn't cause us to overreach the buffer */
396*90e502c7SAndroid Build Coastguard Worker if (current + len > end)
397*90e502c7SAndroid Build Coastguard Worker len = end - current;
398*90e502c7SAndroid Build Coastguard Worker
399*90e502c7SAndroid Build Coastguard Worker status = srtp_cipher_encrypt(c, current, &len);
400*90e502c7SAndroid Build Coastguard Worker if (status)
401*90e502c7SAndroid Build Coastguard Worker return status;
402*90e502c7SAndroid Build Coastguard Worker
403*90e502c7SAndroid Build Coastguard Worker /* advance pointer into buffer1 to reflect encryption */
404*90e502c7SAndroid Build Coastguard Worker current += len;
405*90e502c7SAndroid Build Coastguard Worker
406*90e502c7SAndroid Build Coastguard Worker /* if buffer1 is all encrypted, break out of loop */
407*90e502c7SAndroid Build Coastguard Worker if (current == end)
408*90e502c7SAndroid Build Coastguard Worker break;
409*90e502c7SAndroid Build Coastguard Worker }
410*90e502c7SAndroid Build Coastguard Worker
411*90e502c7SAndroid Build Coastguard Worker /* compare buffers */
412*90e502c7SAndroid Build Coastguard Worker for (j = 0; j < (int)buflen; j++) {
413*90e502c7SAndroid Build Coastguard Worker if (buffer0[j] != buffer1[j]) {
414*90e502c7SAndroid Build Coastguard Worker #if PRINT_DEBUG
415*90e502c7SAndroid Build Coastguard Worker printf("test case %d failed at byte %d\n", i, j);
416*90e502c7SAndroid Build Coastguard Worker printf("computed: %s\n",
417*90e502c7SAndroid Build Coastguard Worker octet_string_hex_string(buffer1, buflen));
418*90e502c7SAndroid Build Coastguard Worker printf("expected: %s\n",
419*90e502c7SAndroid Build Coastguard Worker octet_string_hex_string(buffer0, buflen));
420*90e502c7SAndroid Build Coastguard Worker #endif
421*90e502c7SAndroid Build Coastguard Worker return srtp_err_status_algo_fail;
422*90e502c7SAndroid Build Coastguard Worker }
423*90e502c7SAndroid Build Coastguard Worker }
424*90e502c7SAndroid Build Coastguard Worker }
425*90e502c7SAndroid Build Coastguard Worker
426*90e502c7SAndroid Build Coastguard Worker printf("passed\n");
427*90e502c7SAndroid Build Coastguard Worker
428*90e502c7SAndroid Build Coastguard Worker return srtp_err_status_ok;
429*90e502c7SAndroid Build Coastguard Worker }
430*90e502c7SAndroid Build Coastguard Worker
431*90e502c7SAndroid Build Coastguard Worker /*
432*90e502c7SAndroid Build Coastguard Worker * The function cipher_test_throughput_array() tests the effect of CPU
433*90e502c7SAndroid Build Coastguard Worker * cache thrash on cipher throughput.
434*90e502c7SAndroid Build Coastguard Worker *
435*90e502c7SAndroid Build Coastguard Worker * cipher_array_alloc_init(ctype, array, num_ciphers) creates an array
436*90e502c7SAndroid Build Coastguard Worker * of srtp_cipher_t of type ctype
437*90e502c7SAndroid Build Coastguard Worker */
438*90e502c7SAndroid Build Coastguard Worker
cipher_array_alloc_init(srtp_cipher_t *** ca,int num_ciphers,srtp_cipher_type_t * ctype,int klen)439*90e502c7SAndroid Build Coastguard Worker srtp_err_status_t cipher_array_alloc_init(srtp_cipher_t ***ca,
440*90e502c7SAndroid Build Coastguard Worker int num_ciphers,
441*90e502c7SAndroid Build Coastguard Worker srtp_cipher_type_t *ctype,
442*90e502c7SAndroid Build Coastguard Worker int klen)
443*90e502c7SAndroid Build Coastguard Worker {
444*90e502c7SAndroid Build Coastguard Worker int i, j;
445*90e502c7SAndroid Build Coastguard Worker srtp_err_status_t status;
446*90e502c7SAndroid Build Coastguard Worker uint8_t *key;
447*90e502c7SAndroid Build Coastguard Worker srtp_cipher_t **cipher_array;
448*90e502c7SAndroid Build Coastguard Worker /* pad klen allocation, to handle aes_icm reading 16 bytes for the
449*90e502c7SAndroid Build Coastguard Worker 14-byte salt */
450*90e502c7SAndroid Build Coastguard Worker int klen_pad = ((klen + 15) >> 4) << 4;
451*90e502c7SAndroid Build Coastguard Worker
452*90e502c7SAndroid Build Coastguard Worker /* allocate array of pointers to ciphers */
453*90e502c7SAndroid Build Coastguard Worker cipher_array = (srtp_cipher_t **)srtp_crypto_alloc(sizeof(srtp_cipher_t *) *
454*90e502c7SAndroid Build Coastguard Worker num_ciphers);
455*90e502c7SAndroid Build Coastguard Worker if (cipher_array == NULL)
456*90e502c7SAndroid Build Coastguard Worker return srtp_err_status_alloc_fail;
457*90e502c7SAndroid Build Coastguard Worker
458*90e502c7SAndroid Build Coastguard Worker /* set ca to location of cipher_array */
459*90e502c7SAndroid Build Coastguard Worker *ca = cipher_array;
460*90e502c7SAndroid Build Coastguard Worker
461*90e502c7SAndroid Build Coastguard Worker /* allocate key */
462*90e502c7SAndroid Build Coastguard Worker key = srtp_crypto_alloc(klen_pad);
463*90e502c7SAndroid Build Coastguard Worker if (key == NULL) {
464*90e502c7SAndroid Build Coastguard Worker srtp_crypto_free(cipher_array);
465*90e502c7SAndroid Build Coastguard Worker return srtp_err_status_alloc_fail;
466*90e502c7SAndroid Build Coastguard Worker }
467*90e502c7SAndroid Build Coastguard Worker
468*90e502c7SAndroid Build Coastguard Worker /* allocate and initialize an array of ciphers */
469*90e502c7SAndroid Build Coastguard Worker for (i = 0; i < num_ciphers; i++) {
470*90e502c7SAndroid Build Coastguard Worker /* allocate cipher */
471*90e502c7SAndroid Build Coastguard Worker status = srtp_cipher_type_alloc(ctype, cipher_array, klen, 16);
472*90e502c7SAndroid Build Coastguard Worker if (status)
473*90e502c7SAndroid Build Coastguard Worker return status;
474*90e502c7SAndroid Build Coastguard Worker
475*90e502c7SAndroid Build Coastguard Worker /* generate random key and initialize cipher */
476*90e502c7SAndroid Build Coastguard Worker srtp_cipher_rand_for_tests(key, klen);
477*90e502c7SAndroid Build Coastguard Worker for (j = klen; j < klen_pad; j++)
478*90e502c7SAndroid Build Coastguard Worker key[j] = 0;
479*90e502c7SAndroid Build Coastguard Worker status = srtp_cipher_init(*cipher_array, key);
480*90e502c7SAndroid Build Coastguard Worker if (status)
481*90e502c7SAndroid Build Coastguard Worker return status;
482*90e502c7SAndroid Build Coastguard Worker
483*90e502c7SAndroid Build Coastguard Worker /* printf("%dth cipher is at %p\n", i, *cipher_array); */
484*90e502c7SAndroid Build Coastguard Worker /* printf("%dth cipher description: %s\n", i, */
485*90e502c7SAndroid Build Coastguard Worker /* (*cipher_array)->type->description); */
486*90e502c7SAndroid Build Coastguard Worker
487*90e502c7SAndroid Build Coastguard Worker /* advance cipher array pointer */
488*90e502c7SAndroid Build Coastguard Worker cipher_array++;
489*90e502c7SAndroid Build Coastguard Worker }
490*90e502c7SAndroid Build Coastguard Worker
491*90e502c7SAndroid Build Coastguard Worker srtp_crypto_free(key);
492*90e502c7SAndroid Build Coastguard Worker
493*90e502c7SAndroid Build Coastguard Worker return srtp_err_status_ok;
494*90e502c7SAndroid Build Coastguard Worker }
495*90e502c7SAndroid Build Coastguard Worker
cipher_array_delete(srtp_cipher_t * cipher_array[],int num_cipher)496*90e502c7SAndroid Build Coastguard Worker srtp_err_status_t cipher_array_delete(srtp_cipher_t *cipher_array[],
497*90e502c7SAndroid Build Coastguard Worker int num_cipher)
498*90e502c7SAndroid Build Coastguard Worker {
499*90e502c7SAndroid Build Coastguard Worker int i;
500*90e502c7SAndroid Build Coastguard Worker
501*90e502c7SAndroid Build Coastguard Worker for (i = 0; i < num_cipher; i++) {
502*90e502c7SAndroid Build Coastguard Worker srtp_cipher_dealloc(cipher_array[i]);
503*90e502c7SAndroid Build Coastguard Worker }
504*90e502c7SAndroid Build Coastguard Worker
505*90e502c7SAndroid Build Coastguard Worker srtp_crypto_free(cipher_array);
506*90e502c7SAndroid Build Coastguard Worker
507*90e502c7SAndroid Build Coastguard Worker return srtp_err_status_ok;
508*90e502c7SAndroid Build Coastguard Worker }
509*90e502c7SAndroid Build Coastguard Worker
510*90e502c7SAndroid Build Coastguard Worker /*
511*90e502c7SAndroid Build Coastguard Worker * cipher_array_bits_per_second(c, l, t) computes (an estimate of) the
512*90e502c7SAndroid Build Coastguard Worker * number of bits that a cipher implementation can encrypt in a second
513*90e502c7SAndroid Build Coastguard Worker * when distinct keys are used to encrypt distinct messages
514*90e502c7SAndroid Build Coastguard Worker *
515*90e502c7SAndroid Build Coastguard Worker * c is a cipher (which MUST be allocated an initialized already), l
516*90e502c7SAndroid Build Coastguard Worker * is the length in octets of the test data to be encrypted, and t is
517*90e502c7SAndroid Build Coastguard Worker * the number of trials
518*90e502c7SAndroid Build Coastguard Worker *
519*90e502c7SAndroid Build Coastguard Worker * if an error is encountered, the value 0 is returned
520*90e502c7SAndroid Build Coastguard Worker */
521*90e502c7SAndroid Build Coastguard Worker
cipher_array_bits_per_second(srtp_cipher_t * cipher_array[],int num_cipher,unsigned octets_in_buffer,int num_trials)522*90e502c7SAndroid Build Coastguard Worker uint64_t cipher_array_bits_per_second(srtp_cipher_t *cipher_array[],
523*90e502c7SAndroid Build Coastguard Worker int num_cipher,
524*90e502c7SAndroid Build Coastguard Worker unsigned octets_in_buffer,
525*90e502c7SAndroid Build Coastguard Worker int num_trials)
526*90e502c7SAndroid Build Coastguard Worker {
527*90e502c7SAndroid Build Coastguard Worker int i;
528*90e502c7SAndroid Build Coastguard Worker v128_t nonce;
529*90e502c7SAndroid Build Coastguard Worker clock_t timer;
530*90e502c7SAndroid Build Coastguard Worker unsigned char *enc_buf;
531*90e502c7SAndroid Build Coastguard Worker int cipher_index = srtp_cipher_rand_u32_for_tests() % num_cipher;
532*90e502c7SAndroid Build Coastguard Worker
533*90e502c7SAndroid Build Coastguard Worker /* Over-alloc, for NIST CBC padding */
534*90e502c7SAndroid Build Coastguard Worker enc_buf = srtp_crypto_alloc(octets_in_buffer + 17);
535*90e502c7SAndroid Build Coastguard Worker if (enc_buf == NULL)
536*90e502c7SAndroid Build Coastguard Worker return 0; /* indicate bad parameters by returning null */
537*90e502c7SAndroid Build Coastguard Worker
538*90e502c7SAndroid Build Coastguard Worker /* time repeated trials */
539*90e502c7SAndroid Build Coastguard Worker v128_set_to_zero(&nonce);
540*90e502c7SAndroid Build Coastguard Worker timer = clock();
541*90e502c7SAndroid Build Coastguard Worker for (i = 0; i < num_trials; i++, nonce.v32[3] = i) {
542*90e502c7SAndroid Build Coastguard Worker /* length parameter to srtp_cipher_encrypt is in/out -- out is total,
543*90e502c7SAndroid Build Coastguard Worker * padded
544*90e502c7SAndroid Build Coastguard Worker * length -- so reset it each time. */
545*90e502c7SAndroid Build Coastguard Worker unsigned octets_to_encrypt = octets_in_buffer;
546*90e502c7SAndroid Build Coastguard Worker
547*90e502c7SAndroid Build Coastguard Worker /* encrypt buffer with cipher */
548*90e502c7SAndroid Build Coastguard Worker srtp_cipher_set_iv(cipher_array[cipher_index], (uint8_t *)&nonce,
549*90e502c7SAndroid Build Coastguard Worker srtp_direction_encrypt);
550*90e502c7SAndroid Build Coastguard Worker srtp_cipher_encrypt(cipher_array[cipher_index], enc_buf,
551*90e502c7SAndroid Build Coastguard Worker &octets_to_encrypt);
552*90e502c7SAndroid Build Coastguard Worker
553*90e502c7SAndroid Build Coastguard Worker /* choose a cipher at random from the array*/
554*90e502c7SAndroid Build Coastguard Worker cipher_index = (*((uint32_t *)enc_buf)) % num_cipher;
555*90e502c7SAndroid Build Coastguard Worker }
556*90e502c7SAndroid Build Coastguard Worker timer = clock() - timer;
557*90e502c7SAndroid Build Coastguard Worker
558*90e502c7SAndroid Build Coastguard Worker srtp_crypto_free(enc_buf);
559*90e502c7SAndroid Build Coastguard Worker
560*90e502c7SAndroid Build Coastguard Worker if (timer == 0) {
561*90e502c7SAndroid Build Coastguard Worker /* Too fast! */
562*90e502c7SAndroid Build Coastguard Worker return 0;
563*90e502c7SAndroid Build Coastguard Worker }
564*90e502c7SAndroid Build Coastguard Worker
565*90e502c7SAndroid Build Coastguard Worker return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer;
566*90e502c7SAndroid Build Coastguard Worker }
567*90e502c7SAndroid Build Coastguard Worker
cipher_array_test_throughput(srtp_cipher_t * ca[],int num_cipher)568*90e502c7SAndroid Build Coastguard Worker void cipher_array_test_throughput(srtp_cipher_t *ca[], int num_cipher)
569*90e502c7SAndroid Build Coastguard Worker {
570*90e502c7SAndroid Build Coastguard Worker int i;
571*90e502c7SAndroid Build Coastguard Worker int min_enc_len = 16;
572*90e502c7SAndroid Build Coastguard Worker int max_enc_len = 2048; /* should be a power of two */
573*90e502c7SAndroid Build Coastguard Worker int num_trials = 1000000;
574*90e502c7SAndroid Build Coastguard Worker
575*90e502c7SAndroid Build Coastguard Worker printf("timing %s throughput with key length %d, array size %d:\n",
576*90e502c7SAndroid Build Coastguard Worker (ca[0])->type->description, (ca[0])->key_len, num_cipher);
577*90e502c7SAndroid Build Coastguard Worker fflush(stdout);
578*90e502c7SAndroid Build Coastguard Worker for (i = min_enc_len; i <= max_enc_len; i = i * 4)
579*90e502c7SAndroid Build Coastguard Worker printf("msg len: %d\tgigabits per second: %f\n", i,
580*90e502c7SAndroid Build Coastguard Worker cipher_array_bits_per_second(ca, num_cipher, i, num_trials) /
581*90e502c7SAndroid Build Coastguard Worker 1e9);
582*90e502c7SAndroid Build Coastguard Worker }
583*90e502c7SAndroid Build Coastguard Worker
cipher_driver_test_array_throughput(srtp_cipher_type_t * ct,int klen,int num_cipher)584*90e502c7SAndroid Build Coastguard Worker srtp_err_status_t cipher_driver_test_array_throughput(srtp_cipher_type_t *ct,
585*90e502c7SAndroid Build Coastguard Worker int klen,
586*90e502c7SAndroid Build Coastguard Worker int num_cipher)
587*90e502c7SAndroid Build Coastguard Worker {
588*90e502c7SAndroid Build Coastguard Worker srtp_cipher_t **ca = NULL;
589*90e502c7SAndroid Build Coastguard Worker srtp_err_status_t status;
590*90e502c7SAndroid Build Coastguard Worker
591*90e502c7SAndroid Build Coastguard Worker status = cipher_array_alloc_init(&ca, num_cipher, ct, klen);
592*90e502c7SAndroid Build Coastguard Worker if (status) {
593*90e502c7SAndroid Build Coastguard Worker printf("error: cipher_array_alloc_init() failed with error code %d\n",
594*90e502c7SAndroid Build Coastguard Worker status);
595*90e502c7SAndroid Build Coastguard Worker return status;
596*90e502c7SAndroid Build Coastguard Worker }
597*90e502c7SAndroid Build Coastguard Worker
598*90e502c7SAndroid Build Coastguard Worker cipher_array_test_throughput(ca, num_cipher);
599*90e502c7SAndroid Build Coastguard Worker
600*90e502c7SAndroid Build Coastguard Worker cipher_array_delete(ca, num_cipher);
601*90e502c7SAndroid Build Coastguard Worker
602*90e502c7SAndroid Build Coastguard Worker return srtp_err_status_ok;
603*90e502c7SAndroid Build Coastguard Worker }
604