cryptotest.c revision 167755
1134911Ssam/*- 2134911Ssam * Copyright (c) 2004 Sam Leffler, Errno Consulting 3134911Ssam * All rights reserved. 4134911Ssam * 5134911Ssam * Redistribution and use in source and binary forms, with or without 6134911Ssam * modification, are permitted provided that the following conditions 7134911Ssam * are met: 8134911Ssam * 1. Redistributions of source code must retain the above copyright 9134911Ssam * notice, this list of conditions and the following disclaimer, 10134911Ssam * without modification. 11134911Ssam * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12134911Ssam * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13134911Ssam * redistribution must be conditioned upon including a substantially 14134911Ssam * similar Disclaimer requirement for further binary redistribution. 15134911Ssam * 3. Neither the names of the above-listed copyright holders nor the names 16134911Ssam * of any contributors may be used to endorse or promote products derived 17134911Ssam * from this software without specific prior written permission. 18134911Ssam * 19134911Ssam * NO WARRANTY 20134911Ssam * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21134911Ssam * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22134911Ssam * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 23134911Ssam * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 24134911Ssam * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 25134911Ssam * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26134911Ssam * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27134911Ssam * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 28134911Ssam * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29134911Ssam * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30134911Ssam * THE POSSIBILITY OF SUCH DAMAGES. 31134911Ssam * 32134911Ssam * $FreeBSD: head/tools/tools/crypto/cryptotest.c 167755 2007-03-21 03:42:51Z sam $ 33134911Ssam */ 34134911Ssam 35134911Ssam/* 36134911Ssam * Simple tool for testing hardware/system crypto support. 37134911Ssam * 38134911Ssam * cryptotest [-czsbv] [-a algorithm] [count] [size ...] 39134911Ssam * 40134911Ssam * Run count iterations of a crypt+decrypt or mac operation on a buffer of 41134911Ssam * size bytes. A random key and iv are used. Options: 42134911Ssam * -c check the results 43167755Ssam * -d dev pin work on device dev 44134911Ssam * -z run all available algorithms on a variety of buffer sizes 45134911Ssam * -v be verbose 46134911Ssam * -b mark operations for batching 47134911Ssam * -p profile kernel crypto operations (must be root) 48134911Ssam * -t n fork n threads and run tests concurrently 49134911Ssam * Known algorithms are: 50134911Ssam * null null cbc 51134911Ssam * des des cbc 52134911Ssam * 3des 3des cbc 53134911Ssam * blf blowfish cbc 54134911Ssam * cast cast cbc 55134911Ssam * skj skipjack cbc 56134911Ssam * aes rijndael/aes 128-bit cbc 57134911Ssam * aes192 rijndael/aes 192-bit cbc 58134911Ssam * aes256 rijndael/aes 256-bit cbc 59134911Ssam * md5 md5 hmac 60134911Ssam * sha1 sha1 hmac 61134911Ssam * sha256 256-bit sha2 hmac 62134911Ssam * sha384 384-bit sha2 hmac 63134911Ssam * sha512 512--bit sha2 hmac 64134911Ssam * 65134911Ssam * For a test of how fast a crypto card is, use something like: 66134911Ssam * cryptotest -z 1024 67134911Ssam * This will run a series of tests using the available crypto/cipher 68134911Ssam * algorithms over a variety of buffer sizes. The 1024 says to do 1024 69134911Ssam * iterations. Extra arguments can be used to specify one or more buffer 70134911Ssam * sizes to use in doing tests. 71134911Ssam * 72134911Ssam * To fork multiple processes all doing the same work, specify -t X on the 73134911Ssam * command line to get X "threads" running simultaneously. No effort is made 74134911Ssam * to synchronize the threads or otherwise maximize load. 75134911Ssam * 76134911Ssam * If the kernel crypto code is built with CRYPTO_TIMING and you run as root, 77134911Ssam * then you can specify the -p option to get a "profile" of the time spent 78134911Ssam * processing crypto operations. At present this data is only meaningful for 79134911Ssam * symmetric operations. To get meaningful numbers you must run on an idle 80134911Ssam * machine. 81134911Ssam * 82134911Ssam * Expect ~400 Mb/s for a Broadcom 582x for 8K buffers on a reasonable CPU 83134911Ssam * (64-bit PCI helps). Hifn 7811 parts top out at ~110 Mb/s. 84134911Ssam */ 85134911Ssam#include <sys/types.h> 86134911Ssam#include <sys/param.h> 87134911Ssam#include <sys/time.h> 88134911Ssam#include <sys/ioctl.h> 89134911Ssam#include <stdio.h> 90134911Ssam#include <fcntl.h> 91134911Ssam#include <unistd.h> 92134911Ssam#include <sys/wait.h> 93134911Ssam#include <sys/mman.h> 94134911Ssam#include <paths.h> 95134911Ssam#include <stdlib.h> 96134911Ssam 97134911Ssam#include <sys/sysctl.h> 98134911Ssam#include <sys/time.h> 99134911Ssam#include <crypto/cryptodev.h> 100134911Ssam 101134911Ssam#define CHUNK 64 /* how much to display */ 102134911Ssam#define N(a) (sizeof (a) / sizeof (a[0])) 103134911Ssam#define streq(a,b) (strcasecmp(a,b) == 0) 104134911Ssam 105134911Ssamvoid hexdump(char *, int); 106134911Ssam 107134911Ssamint verbose = 0; 108134911Ssamint opflags = 0; 109134911Ssamint verify = 0; 110167755Ssamint crid = CRYPTO_FLAG_HARDWARE; 111134911Ssam 112134911Ssamstruct alg { 113134911Ssam const char* name; 114134911Ssam int ishash; 115134911Ssam int blocksize; 116134911Ssam int minkeylen; 117134911Ssam int maxkeylen; 118134911Ssam int code; 119134911Ssam} algorithms[] = { 120134911Ssam#ifdef CRYPTO_NULL_CBC 121134911Ssam { "null", 0, 8, 1, 256, CRYPTO_NULL_CBC }, 122134911Ssam#endif 123134911Ssam { "des", 0, 8, 8, 8, CRYPTO_DES_CBC }, 124134911Ssam { "3des", 0, 8, 24, 24, CRYPTO_3DES_CBC }, 125134911Ssam { "blf", 0, 8, 5, 56, CRYPTO_BLF_CBC }, 126134911Ssam { "cast", 0, 8, 5, 16, CRYPTO_CAST_CBC }, 127134911Ssam { "skj", 0, 8, 10, 10, CRYPTO_SKIPJACK_CBC }, 128134911Ssam { "aes", 0, 16, 16, 16, CRYPTO_RIJNDAEL128_CBC}, 129134911Ssam { "aes192", 0, 16, 24, 24, CRYPTO_RIJNDAEL128_CBC}, 130134911Ssam { "aes256", 0, 16, 32, 32, CRYPTO_RIJNDAEL128_CBC}, 131134911Ssam#ifdef notdef 132134911Ssam { "arc4", 0, 8, 1, 32, CRYPTO_ARC4 }, 133134911Ssam#endif 134134911Ssam { "md5", 1, 8, 16, 16, CRYPTO_MD5_HMAC }, 135134911Ssam { "sha1", 1, 8, 20, 20, CRYPTO_SHA1_HMAC }, 136158886Smr { "sha256", 1, 8, 32, 32, CRYPTO_SHA2_256_HMAC }, 137158886Smr { "sha384", 1, 8, 48, 48, CRYPTO_SHA2_384_HMAC }, 138158886Smr { "sha512", 1, 8, 64, 64, CRYPTO_SHA2_512_HMAC }, 139134911Ssam}; 140134911Ssam 141134911Ssamstatic void 142134911Ssamusage(const char* cmd) 143134911Ssam{ 144167755Ssam printf("usage: %s [-czsbv] [-d dev] [-a algorithm] [count] [size ...]\n", 145134911Ssam cmd); 146134911Ssam printf("where algorithm is one of:\n"); 147134911Ssam printf(" des 3des (default) blowfish cast skipjack\n"); 148134911Ssam printf(" aes (aka rijndael) aes192 aes256 arc4\n"); 149134911Ssam printf("count is the number of encrypt/decrypt ops to do\n"); 150134911Ssam printf("size is the number of bytes of text to encrypt+decrypt\n"); 151134911Ssam printf("\n"); 152134911Ssam printf("-c check the results (slows timing)\n"); 153167755Ssam printf("-d use specific device\n"); 154134911Ssam printf("-z run all available algorithms on a variety of sizes\n"); 155134911Ssam printf("-v be verbose\n"); 156134911Ssam printf("-b mark operations for batching\n"); 157134911Ssam printf("-p profile kernel crypto operation (must be root)\n"); 158134911Ssam exit(-1); 159134911Ssam} 160134911Ssam 161134911Ssamstatic struct alg* 162134911Ssamgetalgbycode(int cipher) 163134911Ssam{ 164134911Ssam int i; 165134911Ssam 166134911Ssam for (i = 0; i < N(algorithms); i++) 167134911Ssam if (cipher == algorithms[i].code) 168134911Ssam return &algorithms[i]; 169134911Ssam return NULL; 170134911Ssam} 171134911Ssam 172134911Ssamstatic struct alg* 173134911Ssamgetalgbyname(const char* name) 174134911Ssam{ 175134911Ssam int i; 176134911Ssam 177134911Ssam for (i = 0; i < N(algorithms); i++) 178134911Ssam if (streq(name, algorithms[i].name)) 179134911Ssam return &algorithms[i]; 180134911Ssam return NULL; 181134911Ssam} 182134911Ssam 183134911Ssamstatic int 184134911Ssamdevcrypto(void) 185134911Ssam{ 186134911Ssam static int fd = -1; 187134911Ssam 188134911Ssam if (fd < 0) { 189134911Ssam fd = open(_PATH_DEV "crypto", O_RDWR, 0); 190134911Ssam if (fd < 0) 191134911Ssam err(1, _PATH_DEV "crypto"); 192134911Ssam if (fcntl(fd, F_SETFD, 1) == -1) 193134911Ssam err(1, "fcntl(F_SETFD) (devcrypto)"); 194134911Ssam } 195134911Ssam return fd; 196134911Ssam} 197134911Ssam 198134911Ssamstatic int 199167755Ssamcrlookup(const char *devname) 200167755Ssam{ 201167755Ssam struct crypt_find_op find; 202167755Ssam 203167755Ssam find.crid = -1; 204167755Ssam strlcpy(find.name, devname, sizeof(find.name)); 205167755Ssam if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1) 206167755Ssam err(1, "ioctl(CIOCFINDDEV)"); 207167755Ssam return find.crid; 208167755Ssam} 209167755Ssam 210167755Ssamstatic const char * 211167755Ssamcrfind(int crid) 212167755Ssam{ 213167755Ssam static struct crypt_find_op find; 214167755Ssam 215167755Ssam bzero(&find, sizeof(find)); 216167755Ssam find.crid = crid; 217167755Ssam if (ioctl(devcrypto(), CRIOFINDDEV, &find) == -1) 218167755Ssam err(1, "ioctl(CIOCFINDDEV): crid %d", crid); 219167755Ssam return find.name; 220167755Ssam} 221167755Ssam 222167755Ssamstatic int 223134911Ssamcrget(void) 224134911Ssam{ 225134911Ssam int fd; 226134911Ssam 227134911Ssam if (ioctl(devcrypto(), CRIOGET, &fd) == -1) 228134911Ssam err(1, "ioctl(CRIOGET)"); 229134911Ssam if (fcntl(fd, F_SETFD, 1) == -1) 230134911Ssam err(1, "fcntl(F_SETFD) (crget)"); 231134911Ssam return fd; 232134911Ssam} 233134911Ssam 234134911Ssamstatic char 235134911Ssamrdigit(void) 236134911Ssam{ 237134911Ssam const char a[] = { 238134911Ssam 0x10,0x54,0x11,0x48,0x45,0x12,0x4f,0x13,0x49,0x53,0x14,0x41, 239134911Ssam 0x15,0x16,0x4e,0x55,0x54,0x17,0x18,0x4a,0x4f,0x42,0x19,0x01 240134911Ssam }; 241134911Ssam return 0x20+a[random()%N(a)]; 242134911Ssam} 243134911Ssam 244134911Ssamstatic void 245140407Sphkruntest(struct alg *alg, int count, int size, u_long cmd, struct timeval *tv) 246134911Ssam{ 247134911Ssam int i, fd = crget(); 248134911Ssam struct timeval start, stop, dt; 249134911Ssam char *cleartext, *ciphertext, *originaltext; 250167755Ssam struct session2_op sop; 251134911Ssam struct crypt_op cop; 252134911Ssam char iv[8]; 253134911Ssam 254134911Ssam bzero(&sop, sizeof(sop)); 255134911Ssam if (!alg->ishash) { 256134911Ssam sop.keylen = (alg->minkeylen + alg->maxkeylen)/2; 257134911Ssam sop.key = (char *) malloc(sop.keylen); 258134911Ssam if (sop.key == NULL) 259134911Ssam err(1, "malloc (key)"); 260134911Ssam for (i = 0; i < sop.keylen; i++) 261134911Ssam sop.key[i] = rdigit(); 262134911Ssam sop.cipher = alg->code; 263134911Ssam } else { 264134911Ssam sop.mackeylen = (alg->minkeylen + alg->maxkeylen)/2; 265134911Ssam sop.mackey = (char *) malloc(sop.mackeylen); 266134911Ssam if (sop.mackey == NULL) 267134911Ssam err(1, "malloc (mac)"); 268134911Ssam for (i = 0; i < sop.mackeylen; i++) 269134911Ssam sop.mackey[i] = rdigit(); 270134911Ssam sop.mac = alg->code; 271134911Ssam } 272167755Ssam sop.crid = crid; 273134911Ssam if (ioctl(fd, cmd, &sop) < 0) { 274167755Ssam if (cmd == CIOCGSESSION || cmd == CIOCGSESSION2) { 275134911Ssam close(fd); 276134911Ssam if (verbose) { 277134911Ssam printf("cipher %s", alg->name); 278134911Ssam if (alg->ishash) 279134911Ssam printf(" mackeylen %u\n", sop.mackeylen); 280134911Ssam else 281134911Ssam printf(" keylen %u\n", sop.keylen); 282134911Ssam perror("CIOCGSESSION"); 283134911Ssam } 284134911Ssam /* hardware doesn't support algorithm; skip it */ 285134911Ssam return; 286134911Ssam } 287134911Ssam printf("cipher %s keylen %u mackeylen %u\n", 288134911Ssam alg->name, sop.keylen, sop.mackeylen); 289134911Ssam err(1, "CIOCGSESSION"); 290134911Ssam } 291134911Ssam 292134911Ssam originaltext = malloc(3*size); 293134911Ssam if (originaltext == NULL) 294134911Ssam err(1, "malloc (text)"); 295134911Ssam cleartext = originaltext+size; 296134911Ssam ciphertext = cleartext+size; 297134911Ssam for (i = 0; i < size; i++) 298134911Ssam cleartext[i] = rdigit(); 299134911Ssam memcpy(originaltext, cleartext, size); 300134911Ssam for (i = 0; i < N(iv); i++) 301134911Ssam iv[i] = rdigit(); 302134911Ssam 303134911Ssam if (verbose) { 304134911Ssam printf("session = 0x%x\n", sop.ses); 305167755Ssam printf("device = %s\n", crfind(sop.crid)); 306134911Ssam printf("count = %d, size = %d\n", count, size); 307134911Ssam if (!alg->ishash) { 308134911Ssam printf("iv:"); 309134911Ssam hexdump(iv, sizeof iv); 310134911Ssam } 311134911Ssam printf("cleartext:"); 312134911Ssam hexdump(cleartext, MIN(size, CHUNK)); 313134911Ssam } 314134911Ssam 315134911Ssam gettimeofday(&start, NULL); 316134911Ssam if (!alg->ishash) { 317134911Ssam for (i = 0; i < count; i++) { 318134911Ssam cop.ses = sop.ses; 319134911Ssam cop.op = COP_ENCRYPT; 320134911Ssam cop.flags = opflags; 321134911Ssam cop.len = size; 322134911Ssam cop.src = cleartext; 323134911Ssam cop.dst = ciphertext; 324134911Ssam cop.mac = 0; 325134911Ssam cop.iv = iv; 326134911Ssam 327134911Ssam if (ioctl(fd, CIOCCRYPT, &cop) < 0) 328134911Ssam err(1, "ioctl(CIOCCRYPT)"); 329134911Ssam 330134911Ssam if (verify && bcmp(ciphertext, cleartext, size) == 0) { 331134911Ssam printf("cipher text unchanged:"); 332134911Ssam hexdump(ciphertext, size); 333134911Ssam } 334134911Ssam 335134911Ssam memset(cleartext, 'x', MIN(size, CHUNK)); 336134911Ssam cop.ses = sop.ses; 337134911Ssam cop.op = COP_DECRYPT; 338134911Ssam cop.flags = opflags; 339134911Ssam cop.len = size; 340134911Ssam cop.src = ciphertext; 341134911Ssam cop.dst = cleartext; 342134911Ssam cop.mac = 0; 343134911Ssam cop.iv = iv; 344134911Ssam 345134911Ssam if (ioctl(fd, CIOCCRYPT, &cop) < 0) 346134911Ssam err(1, "ioctl(CIOCCRYPT)"); 347134911Ssam 348134911Ssam if (verify && bcmp(cleartext, originaltext, size) != 0) { 349134911Ssam printf("decrypt mismatch:\n"); 350134911Ssam printf("original:"); 351134911Ssam hexdump(originaltext, size); 352134911Ssam printf("cleartext:"); 353134911Ssam hexdump(cleartext, size); 354134911Ssam } 355134911Ssam } 356134911Ssam } else { 357134911Ssam for (i = 0; i < count; i++) { 358134911Ssam cop.ses = sop.ses; 359134911Ssam cop.op = 0; 360134911Ssam cop.flags = opflags; 361134911Ssam cop.len = size; 362134911Ssam cop.src = cleartext; 363134911Ssam cop.dst = 0; 364134911Ssam cop.mac = ciphertext; 365134911Ssam cop.iv = 0; 366134911Ssam 367134911Ssam if (ioctl(fd, CIOCCRYPT, &cop) < 0) 368134911Ssam err(1, "ioctl(CIOCCRYPT)"); 369134911Ssam } 370134911Ssam } 371134911Ssam gettimeofday(&stop, NULL); 372134911Ssam 373134911Ssam if (ioctl(fd, CIOCFSESSION, &sop.ses) < 0) 374134911Ssam perror("ioctl(CIOCFSESSION)"); 375134911Ssam 376134911Ssam if (verbose) { 377134911Ssam printf("cleartext:"); 378134911Ssam hexdump(cleartext, MIN(size, CHUNK)); 379134911Ssam } 380134911Ssam timersub(&stop, &start, tv); 381134911Ssam 382134911Ssam free(originaltext); 383134911Ssam 384134911Ssam close(fd); 385134911Ssam} 386134911Ssam 387134911Ssam#ifdef __FreeBSD__ 388134911Ssamstatic void 389134911Ssamresetstats() 390134911Ssam{ 391134911Ssam struct cryptostats stats; 392134911Ssam size_t slen; 393134911Ssam 394134911Ssam slen = sizeof (stats); 395140407Sphk if (sysctlbyname("kern.crypto_stats", &stats, &slen, NULL, 0) < 0) { 396134911Ssam perror("kern.crypto_stats"); 397134911Ssam return; 398134911Ssam } 399134911Ssam bzero(&stats.cs_invoke, sizeof (stats.cs_invoke)); 400134911Ssam bzero(&stats.cs_done, sizeof (stats.cs_done)); 401134911Ssam bzero(&stats.cs_cb, sizeof (stats.cs_cb)); 402134911Ssam bzero(&stats.cs_finis, sizeof (stats.cs_finis)); 403134911Ssam stats.cs_invoke.min.tv_sec = 10000; 404134911Ssam stats.cs_done.min.tv_sec = 10000; 405134911Ssam stats.cs_cb.min.tv_sec = 10000; 406134911Ssam stats.cs_finis.min.tv_sec = 10000; 407134911Ssam if (sysctlbyname("kern.crypto_stats", NULL, NULL, &stats, sizeof (stats)) < 0) 408134911Ssam perror("kern.cryptostats"); 409134911Ssam} 410134911Ssam 411134911Ssamstatic void 412134911Ssamprintt(const char* tag, struct cryptotstat *ts) 413134911Ssam{ 414134911Ssam uint64_t avg, min, max; 415134911Ssam 416134911Ssam if (ts->count == 0) 417134911Ssam return; 418134911Ssam avg = (1000000000LL*ts->acc.tv_sec + ts->acc.tv_nsec) / ts->count; 419134911Ssam min = 1000000000LL*ts->min.tv_sec + ts->min.tv_nsec; 420134911Ssam max = 1000000000LL*ts->max.tv_sec + ts->max.tv_nsec; 421134911Ssam printf("%16.16s: avg %6llu ns : min %6llu ns : max %7llu ns [%u samps]\n", 422134911Ssam tag, avg, min, max, ts->count); 423134911Ssam} 424134911Ssam#endif 425134911Ssam 426134911Ssamstatic void 427140407Sphkruntests(struct alg *alg, int count, int size, u_long cmd, int threads, int profile) 428134911Ssam{ 429134911Ssam int i, status; 430134911Ssam double t; 431134911Ssam void *region; 432134911Ssam struct timeval *tvp; 433134911Ssam struct timeval total; 434134911Ssam int otiming; 435134911Ssam 436134911Ssam if (size % alg->blocksize) { 437134911Ssam if (verbose) 438134911Ssam printf("skipping blocksize %u 'cuz not a multiple of " 439134911Ssam "%s blocksize %u\n", 440134911Ssam size, alg->name, alg->blocksize); 441134911Ssam return; 442134911Ssam } 443134911Ssam 444134911Ssam region = mmap(NULL, threads * sizeof (struct timeval), 445134911Ssam PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0); 446134911Ssam if (region == MAP_FAILED) { 447134911Ssam perror("mmap"); 448134911Ssam return; 449134911Ssam } 450134911Ssam tvp = (struct timeval *) region; 451134911Ssam#ifdef __FreeBSD__ 452134911Ssam if (profile) { 453134911Ssam size_t tlen = sizeof (otiming); 454134911Ssam int timing = 1; 455134911Ssam 456134911Ssam resetstats(); 457134911Ssam if (sysctlbyname("debug.crypto_timing", &otiming, &tlen, 458134911Ssam &timing, sizeof (timing)) < 0) 459134911Ssam perror("debug.crypto_timing"); 460134911Ssam } 461134911Ssam#endif 462134911Ssam 463134911Ssam if (threads > 1) { 464134911Ssam for (i = 0; i < threads; i++) 465134911Ssam if (fork() == 0) { 466134911Ssam runtest(alg, count, size, cmd, &tvp[i]); 467134911Ssam exit(0); 468134911Ssam } 469134911Ssam while (waitpid(WAIT_MYPGRP, &status, 0) != -1) 470134911Ssam ; 471134911Ssam } else 472134911Ssam runtest(alg, count, size, cmd, tvp); 473134911Ssam 474134911Ssam t = 0; 475134911Ssam for (i = 0; i < threads; i++) 476134911Ssam t += (((double)tvp[i].tv_sec * 1000000 + tvp[i].tv_usec) / 1000000); 477134911Ssam if (t) { 478134911Ssam int nops = alg->ishash ? count : 2*count; 479134911Ssam 480167755Ssam#if 0 481134911Ssam t /= threads; 482134911Ssam printf("%6.3lf sec, %7d %6s crypts, %7d bytes, %8.0lf byte/sec, %7.1lf Mb/sec\n", 483134911Ssam t, nops, alg->name, size, (double)nops*size / t, 484134911Ssam (double)nops*size / t * 8 / 1024 / 1024); 485167755Ssam#else 486167755Ssam nops *= threads; 487167755Ssam printf("%8.3lf sec, %7d %6s crypts, %7d bytes, %8.0lf byte/sec, %7.1lf Mb/sec\n", 488167755Ssam t, nops, alg->name, size, (double)nops*size / t, 489167755Ssam (double)nops*size / t * 8 / 1024 / 1024); 490167755Ssam#endif 491134911Ssam } 492134911Ssam#ifdef __FreeBSD__ 493134911Ssam if (profile) { 494134911Ssam struct cryptostats stats; 495134911Ssam size_t slen = sizeof (stats); 496134911Ssam 497134911Ssam if (sysctlbyname("debug.crypto_timing", NULL, NULL, 498134911Ssam &otiming, sizeof (otiming)) < 0) 499134911Ssam perror("debug.crypto_timing"); 500140407Sphk if (sysctlbyname("kern.crypto_stats", &stats, &slen, NULL, 0) < 0) 501134911Ssam perror("kern.cryptostats"); 502134911Ssam if (stats.cs_invoke.count) { 503134911Ssam printt("dispatch->invoke", &stats.cs_invoke); 504134911Ssam printt("invoke->done", &stats.cs_done); 505134911Ssam printt("done->cb", &stats.cs_cb); 506134911Ssam printt("cb->finis", &stats.cs_finis); 507134911Ssam } 508134911Ssam } 509134911Ssam#endif 510134911Ssam fflush(stdout); 511134911Ssam} 512134911Ssam 513134911Ssamint 514134911Ssammain(int argc, char **argv) 515134911Ssam{ 516134911Ssam struct alg *alg = NULL; 517134911Ssam int count = 1; 518134911Ssam int sizes[128], nsizes = 0; 519167755Ssam u_long cmd = CIOCGSESSION2; 520134911Ssam int testall = 0; 521134911Ssam int maxthreads = 1; 522134911Ssam int profile = 0; 523134911Ssam int i, ch; 524134911Ssam 525167755Ssam while ((ch = getopt(argc, argv, "cpzsva:bd:t:")) != -1) { 526134911Ssam switch (ch) { 527134911Ssam#ifdef CIOCGSSESSION 528134911Ssam case 's': 529134911Ssam cmd = CIOCGSSESSION; 530134911Ssam break; 531134911Ssam#endif 532134911Ssam case 'v': 533134911Ssam verbose++; 534134911Ssam break; 535134911Ssam case 'a': 536134911Ssam alg = getalgbyname(optarg); 537134911Ssam if (alg == NULL) { 538134911Ssam if (streq(optarg, "rijndael")) 539134911Ssam alg = getalgbyname("aes"); 540134911Ssam else 541134911Ssam usage(argv[0]); 542134911Ssam } 543134911Ssam break; 544167755Ssam case 'd': 545167755Ssam crid = crlookup(optarg); 546167755Ssam break; 547134911Ssam case 't': 548134911Ssam maxthreads = atoi(optarg); 549134911Ssam break; 550134911Ssam case 'z': 551134911Ssam testall = 1; 552134911Ssam break; 553134911Ssam case 'p': 554134911Ssam profile = 1; 555134911Ssam break; 556134911Ssam case 'b': 557134911Ssam opflags |= COP_F_BATCH; 558134911Ssam break; 559134911Ssam case 'c': 560134911Ssam verify = 1; 561134911Ssam break; 562134911Ssam default: 563134911Ssam usage(argv[0]); 564134911Ssam } 565134911Ssam } 566134911Ssam argc -= optind, argv += optind; 567134911Ssam if (argc > 0) 568134911Ssam count = atoi(argv[0]); 569134911Ssam while (argc > 1) { 570134911Ssam int s = atoi(argv[1]); 571134911Ssam if (nsizes < N(sizes)) { 572134911Ssam sizes[nsizes++] = s; 573134911Ssam } else { 574134911Ssam printf("Too many sizes, ignoring %u\n", s); 575134911Ssam } 576134911Ssam argc--, argv++; 577134911Ssam } 578134911Ssam if (nsizes == 0) { 579134911Ssam if (alg) 580134911Ssam sizes[nsizes++] = alg->blocksize; 581134911Ssam else 582134911Ssam sizes[nsizes++] = 8; 583134911Ssam if (testall) { 584134911Ssam while (sizes[nsizes-1] < 8*1024) { 585134911Ssam sizes[nsizes] = sizes[nsizes-1]<<1; 586134911Ssam nsizes++; 587134911Ssam } 588134911Ssam } 589134911Ssam } 590134911Ssam 591134911Ssam if (testall) { 592134911Ssam for (i = 0; i < N(algorithms); i++) { 593134911Ssam int j; 594134911Ssam alg = &algorithms[i]; 595134911Ssam for (j = 0; j < nsizes; j++) 596134911Ssam runtests(alg, count, sizes[j], cmd, maxthreads, profile); 597134911Ssam } 598134911Ssam } else { 599134911Ssam if (alg == NULL) 600134911Ssam alg = getalgbycode(CRYPTO_3DES_CBC); 601134911Ssam for (i = 0; i < nsizes; i++) 602134911Ssam runtests(alg, count, sizes[i], cmd, maxthreads, profile); 603134911Ssam } 604134911Ssam 605134911Ssam return (0); 606134911Ssam} 607134911Ssam 608134911Ssamvoid 609134911Ssamhexdump(char *p, int n) 610134911Ssam{ 611134911Ssam int i, off; 612134911Ssam 613134911Ssam for (off = 0; n > 0; off += 16, n -= 16) { 614134911Ssam printf("%s%04x:", off == 0 ? "\n" : "", off); 615134911Ssam i = (n >= 16 ? 16 : n); 616134911Ssam do { 617134911Ssam printf(" %02x", *p++ & 0xff); 618134911Ssam } while (--i); 619134911Ssam printf("\n"); 620134911Ssam } 621134911Ssam} 622