1/* crypto/des/des_opts.c */ 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58 59/* 60 * define PART1, PART2, PART3 or PART4 to build only with a few of the 61 * options. This is for machines with 64k code segment size restrictions. 62 */ 63 64#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX) 65# define TIMES 66#endif 67 68#include <stdio.h> 69#ifndef OPENSSL_SYS_MSDOS 70# include <openssl/e_os2.h> 71# include OPENSSL_UNISTD 72#else 73# include <io.h> 74extern void exit(); 75#endif 76 77#ifndef OPENSSL_SYS_NETWARE 78# include <signal.h> 79#endif 80 81#ifndef _IRIX 82# include <time.h> 83#endif 84#ifdef TIMES 85# include <sys/types.h> 86# include <sys/times.h> 87#endif 88 89/* 90 * Depending on the VMS version, the tms structure is perhaps defined. The 91 * __TMS macro will show if it was. If it wasn't defined, we should undefine 92 * TIMES, since that tells the rest of the program how things should be 93 * handled. -- Richard Levitte 94 */ 95#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS) 96# undef TIMES 97#endif 98 99#ifndef TIMES 100# include <sys/timeb.h> 101#endif 102 103#if defined(sun) || defined(__ultrix) 104# define _POSIX_SOURCE 105# include <limits.h> 106# include <sys/param.h> 107#endif 108 109#include <openssl/des.h> 110#include "spr.h" 111 112#define DES_DEFAULT_OPTIONS 113 114#if !defined(PART1) && !defined(PART2) && !defined(PART3) && !defined(PART4) 115# define PART1 116# define PART2 117# define PART3 118# define PART4 119#endif 120 121#ifdef PART1 122 123# undef DES_UNROLL 124# undef DES_RISC1 125# undef DES_RISC2 126# undef DES_PTR 127# undef D_ENCRYPT 128# define DES_encrypt1 des_encrypt_u4_cisc_idx 129# define DES_encrypt2 des_encrypt2_u4_cisc_idx 130# define DES_encrypt3 des_encrypt3_u4_cisc_idx 131# define DES_decrypt3 des_decrypt3_u4_cisc_idx 132# undef HEADER_DES_LOCL_H 133# include "des_enc.c" 134 135# define DES_UNROLL 136# undef DES_RISC1 137# undef DES_RISC2 138# undef DES_PTR 139# undef D_ENCRYPT 140# undef DES_encrypt1 141# undef DES_encrypt2 142# undef DES_encrypt3 143# undef DES_decrypt3 144# define DES_encrypt1 des_encrypt_u16_cisc_idx 145# define DES_encrypt2 des_encrypt2_u16_cisc_idx 146# define DES_encrypt3 des_encrypt3_u16_cisc_idx 147# define DES_decrypt3 des_decrypt3_u16_cisc_idx 148# undef HEADER_DES_LOCL_H 149# include "des_enc.c" 150 151# undef DES_UNROLL 152# define DES_RISC1 153# undef DES_RISC2 154# undef DES_PTR 155# undef D_ENCRYPT 156# undef DES_encrypt1 157# undef DES_encrypt2 158# undef DES_encrypt3 159# undef DES_decrypt3 160# define DES_encrypt1 des_encrypt_u4_risc1_idx 161# define DES_encrypt2 des_encrypt2_u4_risc1_idx 162# define DES_encrypt3 des_encrypt3_u4_risc1_idx 163# define DES_decrypt3 des_decrypt3_u4_risc1_idx 164# undef HEADER_DES_LOCL_H 165# include "des_enc.c" 166 167#endif 168 169#ifdef PART2 170 171# undef DES_UNROLL 172# undef DES_RISC1 173# define DES_RISC2 174# undef DES_PTR 175# undef D_ENCRYPT 176# undef DES_encrypt1 177# undef DES_encrypt2 178# undef DES_encrypt3 179# undef DES_decrypt3 180# define DES_encrypt1 des_encrypt_u4_risc2_idx 181# define DES_encrypt2 des_encrypt2_u4_risc2_idx 182# define DES_encrypt3 des_encrypt3_u4_risc2_idx 183# define DES_decrypt3 des_decrypt3_u4_risc2_idx 184# undef HEADER_DES_LOCL_H 185# include "des_enc.c" 186 187# define DES_UNROLL 188# define DES_RISC1 189# undef DES_RISC2 190# undef DES_PTR 191# undef D_ENCRYPT 192# undef DES_encrypt1 193# undef DES_encrypt2 194# undef DES_encrypt3 195# undef DES_decrypt3 196# define DES_encrypt1 des_encrypt_u16_risc1_idx 197# define DES_encrypt2 des_encrypt2_u16_risc1_idx 198# define DES_encrypt3 des_encrypt3_u16_risc1_idx 199# define DES_decrypt3 des_decrypt3_u16_risc1_idx 200# undef HEADER_DES_LOCL_H 201# include "des_enc.c" 202 203# define DES_UNROLL 204# undef DES_RISC1 205# define DES_RISC2 206# undef DES_PTR 207# undef D_ENCRYPT 208# undef DES_encrypt1 209# undef DES_encrypt2 210# undef DES_encrypt3 211# undef DES_decrypt3 212# define DES_encrypt1 des_encrypt_u16_risc2_idx 213# define DES_encrypt2 des_encrypt2_u16_risc2_idx 214# define DES_encrypt3 des_encrypt3_u16_risc2_idx 215# define DES_decrypt3 des_decrypt3_u16_risc2_idx 216# undef HEADER_DES_LOCL_H 217# include "des_enc.c" 218 219#endif 220 221#ifdef PART3 222 223# undef DES_UNROLL 224# undef DES_RISC1 225# undef DES_RISC2 226# define DES_PTR 227# undef D_ENCRYPT 228# undef DES_encrypt1 229# undef DES_encrypt2 230# undef DES_encrypt3 231# undef DES_decrypt3 232# define DES_encrypt1 des_encrypt_u4_cisc_ptr 233# define DES_encrypt2 des_encrypt2_u4_cisc_ptr 234# define DES_encrypt3 des_encrypt3_u4_cisc_ptr 235# define DES_decrypt3 des_decrypt3_u4_cisc_ptr 236# undef HEADER_DES_LOCL_H 237# include "des_enc.c" 238 239# define DES_UNROLL 240# undef DES_RISC1 241# undef DES_RISC2 242# define DES_PTR 243# undef D_ENCRYPT 244# undef DES_encrypt1 245# undef DES_encrypt2 246# undef DES_encrypt3 247# undef DES_decrypt3 248# define DES_encrypt1 des_encrypt_u16_cisc_ptr 249# define DES_encrypt2 des_encrypt2_u16_cisc_ptr 250# define DES_encrypt3 des_encrypt3_u16_cisc_ptr 251# define DES_decrypt3 des_decrypt3_u16_cisc_ptr 252# undef HEADER_DES_LOCL_H 253# include "des_enc.c" 254 255# undef DES_UNROLL 256# define DES_RISC1 257# undef DES_RISC2 258# define DES_PTR 259# undef D_ENCRYPT 260# undef DES_encrypt1 261# undef DES_encrypt2 262# undef DES_encrypt3 263# undef DES_decrypt3 264# define DES_encrypt1 des_encrypt_u4_risc1_ptr 265# define DES_encrypt2 des_encrypt2_u4_risc1_ptr 266# define DES_encrypt3 des_encrypt3_u4_risc1_ptr 267# define DES_decrypt3 des_decrypt3_u4_risc1_ptr 268# undef HEADER_DES_LOCL_H 269# include "des_enc.c" 270 271#endif 272 273#ifdef PART4 274 275# undef DES_UNROLL 276# undef DES_RISC1 277# define DES_RISC2 278# define DES_PTR 279# undef D_ENCRYPT 280# undef DES_encrypt1 281# undef DES_encrypt2 282# undef DES_encrypt3 283# undef DES_decrypt3 284# define DES_encrypt1 des_encrypt_u4_risc2_ptr 285# define DES_encrypt2 des_encrypt2_u4_risc2_ptr 286# define DES_encrypt3 des_encrypt3_u4_risc2_ptr 287# define DES_decrypt3 des_decrypt3_u4_risc2_ptr 288# undef HEADER_DES_LOCL_H 289# include "des_enc.c" 290 291# define DES_UNROLL 292# define DES_RISC1 293# undef DES_RISC2 294# define DES_PTR 295# undef D_ENCRYPT 296# undef DES_encrypt1 297# undef DES_encrypt2 298# undef DES_encrypt3 299# undef DES_decrypt3 300# define DES_encrypt1 des_encrypt_u16_risc1_ptr 301# define DES_encrypt2 des_encrypt2_u16_risc1_ptr 302# define DES_encrypt3 des_encrypt3_u16_risc1_ptr 303# define DES_decrypt3 des_decrypt3_u16_risc1_ptr 304# undef HEADER_DES_LOCL_H 305# include "des_enc.c" 306 307# define DES_UNROLL 308# undef DES_RISC1 309# define DES_RISC2 310# define DES_PTR 311# undef D_ENCRYPT 312# undef DES_encrypt1 313# undef DES_encrypt2 314# undef DES_encrypt3 315# undef DES_decrypt3 316# define DES_encrypt1 des_encrypt_u16_risc2_ptr 317# define DES_encrypt2 des_encrypt2_u16_risc2_ptr 318# define DES_encrypt3 des_encrypt3_u16_risc2_ptr 319# define DES_decrypt3 des_decrypt3_u16_risc2_ptr 320# undef HEADER_DES_LOCL_H 321# include "des_enc.c" 322 323#endif 324 325/* The following if from times(3) man page. It may need to be changed */ 326#ifndef HZ 327# ifndef CLK_TCK 328# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */ 329# define HZ 100.0 330# else /* _BSD_CLK_TCK_ */ 331# define HZ ((double)_BSD_CLK_TCK_) 332# endif 333# else /* CLK_TCK */ 334# define HZ ((double)CLK_TCK) 335# endif 336#endif 337 338#define BUFSIZE ((long)1024) 339long run = 0; 340 341double Time_F(int s); 342#ifdef SIGALRM 343# if defined(__STDC__) || defined(sgi) 344# define SIGRETTYPE void 345# else 346# define SIGRETTYPE int 347# endif 348 349SIGRETTYPE sig_done(int sig); 350SIGRETTYPE sig_done(int sig) 351{ 352 signal(SIGALRM, sig_done); 353 run = 0; 354# ifdef LINT 355 sig = sig; 356# endif 357} 358#endif 359 360#define START 0 361#define STOP 1 362 363double Time_F(int s) 364{ 365 double ret; 366#ifdef TIMES 367 static struct tms tstart, tend; 368 369 if (s == START) { 370 times(&tstart); 371 return (0); 372 } else { 373 times(&tend); 374 ret = ((double)(tend.tms_utime - tstart.tms_utime)) / HZ; 375 return ((ret == 0.0) ? 1e-6 : ret); 376 } 377#else /* !times() */ 378 static struct timeb tstart, tend; 379 long i; 380 381 if (s == START) { 382 ftime(&tstart); 383 return (0); 384 } else { 385 ftime(&tend); 386 i = (long)tend.millitm - (long)tstart.millitm; 387 ret = ((double)(tend.time - tstart.time)) + ((double)i) / 1000.0; 388 return ((ret == 0.0) ? 1e-6 : ret); 389 } 390#endif 391} 392 393#ifdef SIGALRM 394# define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10); 395#else 396# define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb); 397#endif 398 399#define time_it(func,name,index) \ 400 print_name(name); \ 401 Time_F(START); \ 402 for (count=0,run=1; COND(cb); count++) \ 403 { \ 404 unsigned long d[2]; \ 405 func(d,&sch,DES_ENCRYPT); \ 406 } \ 407 tm[index]=Time_F(STOP); \ 408 fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \ 409 tm[index]=((double)COUNT(cb))/tm[index]; 410 411#define print_it(name,index) \ 412 fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \ 413 tm[index]*8,1.0e6/tm[index]); 414 415int main(int argc, char **argv) 416{ 417 long count; 418 static unsigned char buf[BUFSIZE]; 419 static DES_cblock key = 420 { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 }; 421 static DES_cblock key2 = 422 { 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12 }; 423 static DES_cblock key3 = 424 { 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 }; 425 DES_key_schedule sch, sch2, sch3; 426 double d, tm[16], max = 0; 427 int rank[16]; 428 char *str[16]; 429 int max_idx = 0, i, num = 0, j; 430#ifndef SIGALARM 431 long ca, cb, cc, cd, ce; 432#endif 433 434 for (i = 0; i < 12; i++) { 435 tm[i] = 0.0; 436 rank[i] = 0; 437 } 438 439#ifndef TIMES 440 fprintf(stderr, "To get the most accurate results, try to run this\n"); 441 fprintf(stderr, "program when this computer is idle.\n"); 442#endif 443 444 DES_set_key_unchecked(&key, &sch); 445 DES_set_key_unchecked(&key2, &sch2); 446 DES_set_key_unchecked(&key3, &sch3); 447 448#ifndef SIGALRM 449 fprintf(stderr, "First we calculate the approximate speed ...\n"); 450 DES_set_key_unchecked(&key, sch); 451 count = 10; 452 do { 453 long i; 454 unsigned long data[2]; 455 456 count *= 2; 457 Time_F(START); 458 for (i = count; i; i--) 459 DES_encrypt1(data, &(sch[0]), DES_ENCRYPT); 460 d = Time_F(STOP); 461 } while (d < 3.0); 462 ca = count; 463 cb = count * 3; 464 cc = count * 3 * 8 / BUFSIZE + 1; 465 cd = count * 8 / BUFSIZE + 1; 466 467 ce = count / 20 + 1; 468# define COND(d) (count != (d)) 469# define COUNT(d) (d) 470#else 471# define COND(c) (run) 472# define COUNT(d) (count) 473 signal(SIGALRM, sig_done); 474 alarm(10); 475#endif 476 477#ifdef PART1 478 time_it(des_encrypt_u4_cisc_idx, "des_encrypt_u4_cisc_idx ", 0); 479 time_it(des_encrypt_u16_cisc_idx, "des_encrypt_u16_cisc_idx ", 1); 480 time_it(des_encrypt_u4_risc1_idx, "des_encrypt_u4_risc1_idx ", 2); 481 num += 3; 482#endif 483#ifdef PART2 484 time_it(des_encrypt_u16_risc1_idx, "des_encrypt_u16_risc1_idx", 3); 485 time_it(des_encrypt_u4_risc2_idx, "des_encrypt_u4_risc2_idx ", 4); 486 time_it(des_encrypt_u16_risc2_idx, "des_encrypt_u16_risc2_idx", 5); 487 num += 3; 488#endif 489#ifdef PART3 490 time_it(des_encrypt_u4_cisc_ptr, "des_encrypt_u4_cisc_ptr ", 6); 491 time_it(des_encrypt_u16_cisc_ptr, "des_encrypt_u16_cisc_ptr ", 7); 492 time_it(des_encrypt_u4_risc1_ptr, "des_encrypt_u4_risc1_ptr ", 8); 493 num += 3; 494#endif 495#ifdef PART4 496 time_it(des_encrypt_u16_risc1_ptr, "des_encrypt_u16_risc1_ptr", 9); 497 time_it(des_encrypt_u4_risc2_ptr, "des_encrypt_u4_risc2_ptr ", 10); 498 time_it(des_encrypt_u16_risc2_ptr, "des_encrypt_u16_risc2_ptr", 11); 499 num += 3; 500#endif 501 502#ifdef PART1 503 str[0] = " 4 c i"; 504 print_it("des_encrypt_u4_cisc_idx ", 0); 505 max = tm[0]; 506 max_idx = 0; 507 str[1] = "16 c i"; 508 print_it("des_encrypt_u16_cisc_idx ", 1); 509 if (max < tm[1]) { 510 max = tm[1]; 511 max_idx = 1; 512 } 513 str[2] = " 4 r1 i"; 514 print_it("des_encrypt_u4_risc1_idx ", 2); 515 if (max < tm[2]) { 516 max = tm[2]; 517 max_idx = 2; 518 } 519#endif 520#ifdef PART2 521 str[3] = "16 r1 i"; 522 print_it("des_encrypt_u16_risc1_idx", 3); 523 if (max < tm[3]) { 524 max = tm[3]; 525 max_idx = 3; 526 } 527 str[4] = " 4 r2 i"; 528 print_it("des_encrypt_u4_risc2_idx ", 4); 529 if (max < tm[4]) { 530 max = tm[4]; 531 max_idx = 4; 532 } 533 str[5] = "16 r2 i"; 534 print_it("des_encrypt_u16_risc2_idx", 5); 535 if (max < tm[5]) { 536 max = tm[5]; 537 max_idx = 5; 538 } 539#endif 540#ifdef PART3 541 str[6] = " 4 c p"; 542 print_it("des_encrypt_u4_cisc_ptr ", 6); 543 if (max < tm[6]) { 544 max = tm[6]; 545 max_idx = 6; 546 } 547 str[7] = "16 c p"; 548 print_it("des_encrypt_u16_cisc_ptr ", 7); 549 if (max < tm[7]) { 550 max = tm[7]; 551 max_idx = 7; 552 } 553 str[8] = " 4 r1 p"; 554 print_it("des_encrypt_u4_risc1_ptr ", 8); 555 if (max < tm[8]) { 556 max = tm[8]; 557 max_idx = 8; 558 } 559#endif 560#ifdef PART4 561 str[9] = "16 r1 p"; 562 print_it("des_encrypt_u16_risc1_ptr", 9); 563 if (max < tm[9]) { 564 max = tm[9]; 565 max_idx = 9; 566 } 567 str[10] = " 4 r2 p"; 568 print_it("des_encrypt_u4_risc2_ptr ", 10); 569 if (max < tm[10]) { 570 max = tm[10]; 571 max_idx = 10; 572 } 573 str[11] = "16 r2 p"; 574 print_it("des_encrypt_u16_risc2_ptr", 11); 575 if (max < tm[11]) { 576 max = tm[11]; 577 max_idx = 11; 578 } 579#endif 580 printf("options des ecb/s\n"); 581 printf("%s %12.2f 100.0%%\n", str[max_idx], tm[max_idx]); 582 d = tm[max_idx]; 583 tm[max_idx] = -2.0; 584 max = -1.0; 585 for (;;) { 586 for (i = 0; i < 12; i++) { 587 if (max < tm[i]) { 588 max = tm[i]; 589 j = i; 590 } 591 } 592 if (max < 0.0) 593 break; 594 printf("%s %12.2f %4.1f%%\n", str[j], tm[j], tm[j] / d * 100.0); 595 tm[j] = -2.0; 596 max = -1.0; 597 } 598 599 switch (max_idx) { 600 case 0: 601 printf("-DDES_DEFAULT_OPTIONS\n"); 602 break; 603 case 1: 604 printf("-DDES_UNROLL\n"); 605 break; 606 case 2: 607 printf("-DDES_RISC1\n"); 608 break; 609 case 3: 610 printf("-DDES_UNROLL -DDES_RISC1\n"); 611 break; 612 case 4: 613 printf("-DDES_RISC2\n"); 614 break; 615 case 5: 616 printf("-DDES_UNROLL -DDES_RISC2\n"); 617 break; 618 case 6: 619 printf("-DDES_PTR\n"); 620 break; 621 case 7: 622 printf("-DDES_UNROLL -DDES_PTR\n"); 623 break; 624 case 8: 625 printf("-DDES_RISC1 -DDES_PTR\n"); 626 break; 627 case 9: 628 printf("-DDES_UNROLL -DDES_RISC1 -DDES_PTR\n"); 629 break; 630 case 10: 631 printf("-DDES_RISC2 -DDES_PTR\n"); 632 break; 633 case 11: 634 printf("-DDES_UNROLL -DDES_RISC2 -DDES_PTR\n"); 635 break; 636 } 637 exit(0); 638#if defined(LINT) || defined(OPENSSL_SYS_MSDOS) 639 return (0); 640#endif 641} 642