OLD | NEW |
1 /* | 1 /* |
2 * cipher_driver.c | 2 * cipher_driver.c |
3 * | 3 * |
4 * A driver for the generic cipher type | 4 * A driver for the generic cipher type |
5 * | 5 * |
6 * David A. McGrew | 6 * David A. McGrew |
7 * Cisco Systems, Inc. | 7 * Cisco Systems, Inc. |
8 */ | 8 */ |
9 | 9 |
10 /* | 10 /* |
11 * | 11 * |
12 * Copyright (c) 2001-2006, Cisco Systems, Inc. | 12 * Copyright (c) 2001-2006,2013 Cisco Systems, Inc. |
13 * All rights reserved. | 13 * All rights reserved. |
14 * | 14 * |
15 * Redistribution and use in source and binary forms, with or without | 15 * Redistribution and use in source and binary forms, with or without |
16 * modification, are permitted provided that the following conditions | 16 * modification, are permitted provided that the following conditions |
17 * are met: | 17 * are met: |
18 * | 18 * |
19 * Redistributions of source code must retain the above copyright | 19 * Redistributions of source code must retain the above copyright |
20 * notice, this list of conditions and the following disclaimer. | 20 * notice, this list of conditions and the following disclaimer. |
21 * | 21 * |
22 * Redistributions in binary form must reproduce the above | 22 * Redistributions in binary form must reproduce the above |
(...skipping 13 matching lines...) Expand all Loading... |
36 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 36 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
38 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 38 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
41 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | 41 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
42 * OF THE POSSIBILITY OF SUCH DAMAGE. | 42 * OF THE POSSIBILITY OF SUCH DAMAGE. |
43 * | 43 * |
44 */ | 44 */ |
45 | 45 |
| 46 #ifdef HAVE_CONFIG_H |
| 47 #include <config.h> |
| 48 #endif |
| 49 |
46 #include <stdio.h> /* for printf() */ | 50 #include <stdio.h> /* for printf() */ |
47 #include <stdlib.h> /* for rand() */ | 51 #include <stdlib.h> /* for rand() */ |
48 #include <string.h> /* for memset() */ | 52 #include <string.h> /* for memset() */ |
49 #include <unistd.h> /* for getopt() */ | 53 #include <unistd.h> /* for getopt() */ |
50 #include "cipher.h" | 54 #include "cipher.h" |
| 55 #ifdef OPENSSL |
| 56 #include "aes_icm_ossl.h" |
| 57 #include "aes_gcm_ossl.h" |
| 58 #else |
51 #include "aes_icm.h" | 59 #include "aes_icm.h" |
| 60 #endif |
52 #include "null_cipher.h" | 61 #include "null_cipher.h" |
53 | 62 |
54 #define PRINT_DEBUG 0 | 63 #define PRINT_DEBUG 0 |
55 | 64 |
56 void | 65 void |
57 cipher_driver_test_throughput(cipher_t *c); | 66 cipher_driver_test_throughput(cipher_t *c); |
58 | 67 |
59 err_status_t | 68 err_status_t |
60 cipher_driver_self_test(cipher_type_t *ct); | 69 cipher_driver_self_test(cipher_type_t *ct); |
61 | 70 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 } | 116 } |
108 | 117 |
109 /* | 118 /* |
110 * null_cipher, aes_icm, and aes_cbc are the cipher meta-objects | 119 * null_cipher, aes_icm, and aes_cbc are the cipher meta-objects |
111 * defined in the files in crypto/cipher subdirectory. these are | 120 * defined in the files in crypto/cipher subdirectory. these are |
112 * declared external so that we can use these cipher types here | 121 * declared external so that we can use these cipher types here |
113 */ | 122 */ |
114 | 123 |
115 extern cipher_type_t null_cipher; | 124 extern cipher_type_t null_cipher; |
116 extern cipher_type_t aes_icm; | 125 extern cipher_type_t aes_icm; |
| 126 #ifndef OPENSSL |
117 extern cipher_type_t aes_cbc; | 127 extern cipher_type_t aes_cbc; |
| 128 #else |
| 129 #ifndef SRTP_NO_AES192 |
| 130 extern cipher_type_t aes_icm_192; |
| 131 #endif |
| 132 extern cipher_type_t aes_icm_256; |
| 133 extern cipher_type_t aes_gcm_128_openssl; |
| 134 extern cipher_type_t aes_gcm_256_openssl; |
| 135 #endif |
118 | 136 |
119 int | 137 int |
120 main(int argc, char *argv[]) { | 138 main(int argc, char *argv[]) { |
121 cipher_t *c = NULL; | 139 cipher_t *c = NULL; |
122 err_status_t status; | 140 err_status_t status; |
123 unsigned char test_key[48] = { | 141 unsigned char test_key[48] = { |
124 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | 142 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
125 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, | 143 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
126 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, | 144 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, |
127 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, | 145 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 if (do_array_timing_test) { | 182 if (do_array_timing_test) { |
165 int max_num_cipher = 1 << 16; /* number of ciphers in cipher_array */ | 183 int max_num_cipher = 1 << 16; /* number of ciphers in cipher_array */ |
166 int num_cipher; | 184 int num_cipher; |
167 | 185 |
168 for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) | 186 for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) |
169 cipher_driver_test_array_throughput(&null_cipher, 0, num_cipher); | 187 cipher_driver_test_array_throughput(&null_cipher, 0, num_cipher); |
170 | 188 |
171 for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) | 189 for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) |
172 cipher_driver_test_array_throughput(&aes_icm, 30, num_cipher); | 190 cipher_driver_test_array_throughput(&aes_icm, 30, num_cipher); |
173 | 191 |
| 192 #ifndef OPENSSL |
174 for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) | 193 for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) |
175 cipher_driver_test_array_throughput(&aes_icm, 46, num_cipher); | 194 cipher_driver_test_array_throughput(&aes_icm, 46, num_cipher); |
176 | 195 |
177 for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) | 196 for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) |
178 cipher_driver_test_array_throughput(&aes_cbc, 16, num_cipher); | 197 cipher_driver_test_array_throughput(&aes_cbc, 16, num_cipher); |
179 | 198 |
180 for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) | 199 for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) |
181 cipher_driver_test_array_throughput(&aes_cbc, 32, num_cipher); | 200 cipher_driver_test_array_throughput(&aes_cbc, 32, num_cipher); |
| 201 #else |
| 202 #ifndef SRTP_NO_AES192 |
| 203 for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) |
| 204 cipher_driver_test_array_throughput(&aes_icm_192, 38, num_cipher); |
| 205 #endif |
| 206 for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) |
| 207 cipher_driver_test_array_throughput(&aes_icm_256, 46, num_cipher); |
| 208 |
| 209 for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) { |
| 210 cipher_driver_test_array_throughput(&aes_gcm_128_openssl, AES_128_GCM_KE
YSIZE_WSALT, num_cipher); |
| 211 } |
| 212 |
| 213 for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8) { |
| 214 cipher_driver_test_array_throughput(&aes_gcm_256_openssl, AES_256_GCM_KE
YSIZE_WSALT, num_cipher); |
| 215 } |
| 216 #endif |
182 } | 217 } |
183 | 218 |
184 if (do_validation) { | 219 if (do_validation) { |
185 cipher_driver_self_test(&null_cipher); | 220 cipher_driver_self_test(&null_cipher); |
186 cipher_driver_self_test(&aes_icm); | 221 cipher_driver_self_test(&aes_icm); |
| 222 #ifndef OPENSSL |
187 cipher_driver_self_test(&aes_cbc); | 223 cipher_driver_self_test(&aes_cbc); |
| 224 #else |
| 225 #ifndef SRTP_NO_AES192 |
| 226 cipher_driver_self_test(&aes_icm_192); |
| 227 #endif |
| 228 cipher_driver_self_test(&aes_icm_256); |
| 229 cipher_driver_self_test(&aes_gcm_128_openssl); |
| 230 cipher_driver_self_test(&aes_gcm_256_openssl); |
| 231 #endif |
188 } | 232 } |
189 | 233 |
190 /* do timing and/or buffer_test on null_cipher */ | 234 /* do timing and/or buffer_test on null_cipher */ |
191 status = cipher_type_alloc(&null_cipher, &c, 0); | 235 status = cipher_type_alloc(&null_cipher, &c, 0, 0); |
192 check_status(status); | 236 check_status(status); |
193 | 237 |
194 status = cipher_init(c, NULL, direction_encrypt); | 238 status = cipher_init(c, NULL); |
195 check_status(status); | 239 check_status(status); |
196 | 240 |
197 if (do_timing_test) | 241 if (do_timing_test) |
198 cipher_driver_test_throughput(c); | 242 cipher_driver_test_throughput(c); |
199 if (do_validation) { | 243 if (do_validation) { |
200 status = cipher_driver_test_buffering(c); | 244 status = cipher_driver_test_buffering(c); |
201 check_status(status); | 245 check_status(status); |
202 } | 246 } |
203 status = cipher_dealloc(c); | 247 status = cipher_dealloc(c); |
204 check_status(status); | 248 check_status(status); |
205 | 249 |
206 | 250 |
207 /* run the throughput test on the aes_icm cipher (128-bit key) */ | 251 /* run the throughput test on the aes_icm cipher (128-bit key) */ |
208 status = cipher_type_alloc(&aes_icm, &c, 30); | 252 status = cipher_type_alloc(&aes_icm, &c, 30, 0); |
209 if (status) { | 253 if (status) { |
210 fprintf(stderr, "error: can't allocate cipher\n"); | 254 fprintf(stderr, "error: can't allocate cipher\n"); |
211 exit(status); | 255 exit(status); |
212 } | 256 } |
213 | 257 |
214 status = cipher_init(c, test_key, direction_encrypt); | 258 status = cipher_init(c, test_key); |
215 check_status(status); | 259 check_status(status); |
216 | 260 |
217 if (do_timing_test) | 261 if (do_timing_test) |
218 cipher_driver_test_throughput(c); | 262 cipher_driver_test_throughput(c); |
219 | 263 |
220 if (do_validation) { | 264 if (do_validation) { |
221 status = cipher_driver_test_buffering(c); | 265 status = cipher_driver_test_buffering(c); |
222 check_status(status); | 266 check_status(status); |
223 } | 267 } |
224 | 268 |
225 status = cipher_dealloc(c); | 269 status = cipher_dealloc(c); |
226 check_status(status); | 270 check_status(status); |
227 | 271 |
228 /* repeat the tests with 256-bit keys */ | 272 /* repeat the tests with 256-bit keys */ |
229 status = cipher_type_alloc(&aes_icm, &c, 46); | 273 #ifndef OPENSSL |
| 274 status = cipher_type_alloc(&aes_icm, &c, 46, 0); |
| 275 #else |
| 276 status = cipher_type_alloc(&aes_icm_256, &c, 46, 0); |
| 277 #endif |
230 if (status) { | 278 if (status) { |
231 fprintf(stderr, "error: can't allocate cipher\n"); | 279 fprintf(stderr, "error: can't allocate cipher\n"); |
232 exit(status); | 280 exit(status); |
233 } | 281 } |
234 | 282 |
235 status = cipher_init(c, test_key, direction_encrypt); | 283 status = cipher_init(c, test_key); |
236 check_status(status); | 284 check_status(status); |
237 | 285 |
238 if (do_timing_test) | 286 if (do_timing_test) |
239 cipher_driver_test_throughput(c); | 287 cipher_driver_test_throughput(c); |
240 | 288 |
241 if (do_validation) { | 289 if (do_validation) { |
242 status = cipher_driver_test_buffering(c); | 290 status = cipher_driver_test_buffering(c); |
243 check_status(status); | 291 check_status(status); |
244 } | 292 } |
245 | 293 |
246 status = cipher_dealloc(c); | 294 status = cipher_dealloc(c); |
247 check_status(status); | 295 check_status(status); |
248 | 296 |
249 return 0; | 297 #ifdef OPENSSL |
| 298 /* run the throughput test on the aes_gcm_128_openssl cipher */ |
| 299 status = cipher_type_alloc(&aes_gcm_128_openssl, &c, AES_128_GCM_KEYSIZE_WSA
LT, 8); |
| 300 if (status) { |
| 301 fprintf(stderr, "error: can't allocate GCM 128 cipher\n"); |
| 302 exit(status); |
| 303 } |
| 304 status = cipher_init(c, test_key); |
| 305 check_status(status); |
| 306 if (do_timing_test) { |
| 307 cipher_driver_test_throughput(c); |
| 308 } |
| 309 |
| 310 if (do_validation) { |
| 311 status = cipher_driver_test_buffering(c); |
| 312 check_status(status); |
| 313 } |
| 314 status = cipher_dealloc(c); |
| 315 check_status(status); |
| 316 |
| 317 /* run the throughput test on the aes_gcm_256_openssl cipher */ |
| 318 status = cipher_type_alloc(&aes_gcm_256_openssl, &c, AES_256_GCM_KEYSIZE_WSA
LT, 16); |
| 319 if (status) { |
| 320 fprintf(stderr, "error: can't allocate GCM 256 cipher\n"); |
| 321 exit(status); |
| 322 } |
| 323 status = cipher_init(c, test_key); |
| 324 check_status(status); |
| 325 if (do_timing_test) { |
| 326 cipher_driver_test_throughput(c); |
| 327 } |
| 328 |
| 329 if (do_validation) { |
| 330 status = cipher_driver_test_buffering(c); |
| 331 check_status(status); |
| 332 } |
| 333 status = cipher_dealloc(c); |
| 334 check_status(status); |
| 335 #endif |
| 336 |
| 337 return 0; |
250 } | 338 } |
251 | 339 |
252 void | 340 void |
253 cipher_driver_test_throughput(cipher_t *c) { | 341 cipher_driver_test_throughput(cipher_t *c) { |
254 int i; | 342 int i; |
255 int min_enc_len = 32; | 343 int min_enc_len = 32; |
256 int max_enc_len = 2048; /* should be a power of two */ | 344 int max_enc_len = 2048; /* should be a power of two */ |
257 int num_trials = 1000000; | 345 int num_trials = 1000000; |
258 | 346 |
259 printf("timing %s throughput, key length %d:\n", c->type->description, c->key_
len); | 347 printf("timing %s throughput, key length %d:\n", c->type->description, c->key_
len); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 printf("testing output buffering for cipher %s...", | 387 printf("testing output buffering for cipher %s...", |
300 c->type->description); | 388 c->type->description); |
301 | 389 |
302 for (i=0; i < num_trials; i++) { | 390 for (i=0; i < num_trials; i++) { |
303 | 391 |
304 /* set buffers to zero */ | 392 /* set buffers to zero */ |
305 for (j=0; j < buflen; j++) | 393 for (j=0; j < buflen; j++) |
306 buffer0[j] = buffer1[j] = 0; | 394 buffer0[j] = buffer1[j] = 0; |
307 | 395 |
308 /* initialize cipher */ | 396 /* initialize cipher */ |
309 status = cipher_set_iv(c, idx); | 397 status = cipher_set_iv(c, idx, direction_encrypt); |
310 if (status) | 398 if (status) |
311 return status; | 399 return status; |
312 | 400 |
313 /* generate 'reference' value by encrypting all at once */ | 401 /* generate 'reference' value by encrypting all at once */ |
314 status = cipher_encrypt(c, buffer0, &buflen); | 402 status = cipher_encrypt(c, buffer0, &buflen); |
315 if (status) | 403 if (status) |
316 return status; | 404 return status; |
317 | 405 |
318 /* re-initialize cipher */ | 406 /* re-initialize cipher */ |
319 status = cipher_set_iv(c, idx); | 407 status = cipher_set_iv(c, idx, direction_encrypt); |
320 if (status) | 408 if (status) |
321 return status; | 409 return status; |
322 | 410 |
323 /* now loop over short lengths until buffer1 is encrypted */ | 411 /* now loop over short lengths until buffer1 is encrypted */ |
324 current = buffer1; | 412 current = buffer1; |
325 end = buffer1 + buflen; | 413 end = buffer1 + buflen; |
326 while (current < end) { | 414 while (current < end) { |
327 | 415 |
328 /* choose a short length */ | 416 /* choose a short length */ |
329 len = rand() & 0x01f; | 417 len = rand() & 0x01f; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 key = crypto_alloc(klen_pad); | 481 key = crypto_alloc(klen_pad); |
394 if (key == NULL) { | 482 if (key == NULL) { |
395 free(cipher_array); | 483 free(cipher_array); |
396 return err_status_alloc_fail; | 484 return err_status_alloc_fail; |
397 } | 485 } |
398 | 486 |
399 /* allocate and initialize an array of ciphers */ | 487 /* allocate and initialize an array of ciphers */ |
400 for (i=0; i < num_ciphers; i++) { | 488 for (i=0; i < num_ciphers; i++) { |
401 | 489 |
402 /* allocate cipher */ | 490 /* allocate cipher */ |
403 status = cipher_type_alloc(ctype, cipher_array, klen); | 491 status = cipher_type_alloc(ctype, cipher_array, klen, 16); |
404 if (status) | 492 if (status) |
405 return status; | 493 return status; |
406 | 494 |
407 /* generate random key and initialize cipher */ | 495 /* generate random key and initialize cipher */ |
408 for (j=0; j < klen; j++) | 496 for (j=0; j < klen; j++) |
409 key[j] = (uint8_t) rand(); | 497 key[j] = (uint8_t) rand(); |
410 for (; j < klen_pad; j++) | 498 for (; j < klen_pad; j++) |
411 key[j] = 0; | 499 key[j] = 0; |
412 status = cipher_init(*cipher_array, key, direction_encrypt); | 500 status = cipher_init(*cipher_array, key); |
413 if (status) | 501 if (status) |
414 return status; | 502 return status; |
415 | 503 |
416 /* printf("%dth cipher is at %p\n", i, *cipher_array); */ | 504 /* printf("%dth cipher is at %p\n", i, *cipher_array); */ |
417 /* printf("%dth cipher description: %s\n", i, */ | 505 /* printf("%dth cipher description: %s\n", i, */ |
418 /* (*cipher_array)->type->description); */ | 506 /* (*cipher_array)->type->description); */ |
419 | 507 |
420 /* advance cipher array pointer */ | 508 /* advance cipher array pointer */ |
421 cipher_array++; | 509 cipher_array++; |
422 } | 510 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 | 557 |
470 /* time repeated trials */ | 558 /* time repeated trials */ |
471 v128_set_to_zero(&nonce); | 559 v128_set_to_zero(&nonce); |
472 timer = clock(); | 560 timer = clock(); |
473 for(i=0; i < num_trials; i++, nonce.v32[3] = i) { | 561 for(i=0; i < num_trials; i++, nonce.v32[3] = i) { |
474 /* length parameter to cipher_encrypt is in/out -- out is total, padded | 562 /* length parameter to cipher_encrypt is in/out -- out is total, padded |
475 * length -- so reset it each time. */ | 563 * length -- so reset it each time. */ |
476 unsigned octets_to_encrypt = octets_in_buffer; | 564 unsigned octets_to_encrypt = octets_in_buffer; |
477 | 565 |
478 /* encrypt buffer with cipher */ | 566 /* encrypt buffer with cipher */ |
479 cipher_set_iv(cipher_array[cipher_index], &nonce); | 567 cipher_set_iv(cipher_array[cipher_index], &nonce, direction_encrypt); |
480 cipher_encrypt(cipher_array[cipher_index], enc_buf, &octets_to_encrypt); | 568 cipher_encrypt(cipher_array[cipher_index], enc_buf, &octets_to_encrypt); |
481 | 569 |
482 /* choose a cipher at random from the array*/ | 570 /* choose a cipher at random from the array*/ |
483 cipher_index = (*((uint32_t *)enc_buf)) % num_cipher; | 571 cipher_index = (*((uint32_t *)enc_buf)) % num_cipher; |
484 } | 572 } |
485 timer = clock() - timer; | 573 timer = clock() - timer; |
486 | 574 |
487 free(enc_buf); | 575 free(enc_buf); |
488 | 576 |
489 if (timer == 0) { | 577 if (timer == 0) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
522 status); | 610 status); |
523 return status; | 611 return status; |
524 } | 612 } |
525 | 613 |
526 cipher_array_test_throughput(ca, num_cipher); | 614 cipher_array_test_throughput(ca, num_cipher); |
527 | 615 |
528 cipher_array_delete(ca, num_cipher); | 616 cipher_array_delete(ca, num_cipher); |
529 | 617 |
530 return err_status_ok; | 618 return err_status_ok; |
531 } | 619 } |
OLD | NEW |