📄 cryptotest.c
字号:
/*- * Copyright (c) 2004 Sam Leffler, Errno Consulting * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * 3. Neither the names of the above-listed copyright holders nor the names * of any contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. * * $FreeBSD: src/tools/tools/crypto/cryptotest.c,v 1.9 2007/03/21 03:42:51 sam Exp $ *//* * Simple tool for testing hardware/system crypto support. * * cryptotest [-czsbv] [-a algorithm] [count] [size ...] * * Run count iterations of a crypt+decrypt or mac operation on a buffer of * size bytes. A random key and iv are used. Options: * -c check the results * -d dev pin work on device dev * -z run all available algorithms on a variety of buffer sizes * -v be verbose * -b mark operations for batching * -p profile kernel crypto operations (must be root) * -t n fork n threads and run tests concurrently * Known algorithms are: * null null cbc * des des cbc * 3des 3des cbc * blf blowfish cbc * cast cast cbc * skj skipjack cbc * aes rijndael/aes 128-bit cbc * aes192 rijndael/aes 192-bit cbc * aes256 rijndael/aes 256-bit cbc * md5 md5 hmac * md5 md5 hmac * sha1 sha1 * sha1_hmac sha1 hmac * sha256 256-bit sha2 * sha256_hmac 256-bit sha2 hmac * sha384 384-bit sha2 * sha384_hmac 384-bit sha2 hmac * sha512 512--bit sha2 * sha512_hmac 512--bit sha2 hmac * * For a test of how fast a crypto card is, use something like: * cryptotest -z 1024 * This will run a series of tests using the available crypto/cipher * algorithms over a variety of buffer sizes. The 1024 says to do 1024 * iterations. Extra arguments can be used to specify one or more buffer * sizes to use in doing tests. * * To fork multiple processes all doing the same work, specify -t X on the * command line to get X "threads" running simultaneously. No effort is made * to synchronize the threads or otherwise maximize load. * * If the kernel crypto code is built with CRYPTO_TIMING and you run as root, * then you can specify the -p option to get a "profile" of the time spent * processing crypto operations. At present this data is only meaningful for * symmetric operations. To get meaningful numbers you must run on an idle * machine. * * Expect ~400 Mb/s for a Broadcom 582x for 8K buffers on a reasonable CPU * (64-bit PCI helps). Hifn 7811 parts top out at ~110 Mb/s. */#include <sys/types.h>#include <sys/param.h>#include <sys/time.h>#include <sys/ioctl.h>#include <stdio.h>#include <fcntl.h>#include <unistd.h>#include <sys/wait.h>#include <sys/mman.h>#include <paths.h>#include <stdlib.h>#include <string.h>#include <strings.h>#include <err.h>#include <string.h>#include <err.h>#include <sys/sysctl.h>#include <time.h>#include <sys/time.h>#include <crypto/cryptodev.h>#define CHUNK 64 /* how much to display */#define N(a) (sizeof (a) / sizeof (a[0]))#define streq(a,b) (strcasecmp(a,b) == 0)void hexdump(char *, int);int verbose = 0;int opflags = 0;int verify = 0;int crid = CRYPTO_FLAG_HARDWARE | CRYPTO_FLAG_SOFTWARE;int swap_iv = 0;int swap_key = 0;int swap_data = 0;static void swap_buf(char *buf, int len){ int i; char tmp[4]; for (i = 0; i < len; i += 4) { memcpy(tmp, &buf[i], 4); buf[i + 0] = tmp[3]; buf[i + 1] = tmp[2]; buf[i + 2] = tmp[1]; buf[i + 3] = tmp[0]; }}#define MAX_IV_SIZE 16struct alg { const char* name; int ishash; int blocksize; int minkeylen; int maxkeylen; int hashsize; int code;} algorithms[] = {#ifdef CRYPTO_NULL_CBC { "null", 0, 8, 1, 256, 0, CRYPTO_NULL_CBC },#endif { "des", 0, 8, 8, 8, 0, CRYPTO_DES_CBC }, { "3des", 0, 8, 24, 24, 0, CRYPTO_3DES_CBC }, { "blf", 0, 8, 5, 56, 0, CRYPTO_BLF_CBC }, { "cast", 0, 8, 5, 16, 0, CRYPTO_CAST_CBC }, { "skj", 0, 8, 10, 10, 0, CRYPTO_SKIPJACK_CBC }, { "aes", 0, 16, 16, 16, 0, CRYPTO_RIJNDAEL128_CBC}, { "aes192", 0, 16, 24, 24, 0, CRYPTO_RIJNDAEL128_CBC}, { "aes256", 0, 16, 32, 32, 0, CRYPTO_RIJNDAEL128_CBC},#ifdef notdef { "arc4", 0, 8, 1, 32, 0, CRYPTO_ARC4 },#endif { "md5", 1, 8, 0, 0, 16, CRYPTO_MD5 }, { "md5_hmac", 1, 8, 1, 64, 16, CRYPTO_MD5_HMAC }, { "sha1", 1, 8, 0, 0, 20, CRYPTO_SHA1 }, { "sha1_hmac", 1, 1, 1, 64, 20, CRYPTO_SHA1_HMAC }, { "sha256", 1, 8, 0, 0, 32, CRYPTO_SHA2_256 }, { "sha256_hmac", 1, 1, 1, 64, 32, CRYPTO_SHA2_256_HMAC }, { "sha384", 1, 8, 0, 0, 48, CRYPTO_SHA2_384 }, { "sha384_hmac", 1, 1, 1, 64, 48, CRYPTO_SHA2_384_HMAC }, { "sha512", 1, 8, 0, 0, 64, CRYPTO_SHA2_512 }, { "sha512_hmac", 1, 1, 1, 64, 64, CRYPTO_SHA2_512_HMAC },};static voidusage(const char* cmd){ printf("usage: %s [-czsbvVKD] [-d dev] [-a algorithm] [count] [size ...]\n", cmd); printf("where algorithm is one of:\n"); printf(" des 3des (default) blf (blowfish) cast skj (skipjack)\n"); printf(" aes (aka rijndael) aes192 aes256 arc4\n"); printf(" md5 md5_hmac sha1 sha1_hmac sha256 sha256_hmac\n"); printf(" sha384 sha384_hmac sha512 sha512_hmac\n"); printf("count is the number of encrypt/decrypt ops to do\n"); printf("size is the number of bytes of text to encrypt+decrypt\n"); printf("\n"); printf("-c check the results (slows timing)\n"); printf("-d use specific device\n"); printf("-z run all available algorithms on a variety of sizes\n"); printf("-v be verbose\n"); printf("-b mark operations for batching\n"); printf("-p profile kernel crypto operation (must be root)\n"); printf("-V swap IV\n"); printf("-K swap KEY\n"); printf("-D swap DATA\n"); exit(-1);}static struct alg*getalgbycode(int cipher){ int i; for (i = 0; i < N(algorithms); i++) if (cipher == algorithms[i].code) return &algorithms[i]; return NULL;}static struct alg*getalgbyname(const char* name){ int i; for (i = 0; i < N(algorithms); i++) if (streq(name, algorithms[i].name)) return &algorithms[i]; return NULL;}static intdevcrypto(void){ static int fd = -1; if (fd < 0) { fd = open(_PATH_DEV "crypto", O_RDWR, 0); if (fd < 0) err(1, _PATH_DEV "crypto"); if (fcntl(fd, F_SETFD, 1) == -1) err(1, "fcntl(F_SETFD) (devcrypto)"); } return fd;}static intcrlookup(const char *devname){ struct crypt_find_op find; find.crid = -1; strlcpy(find.name, devname, sizeof(find.name)); if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1) err(1, "line %d:ioctl(CIOCFINDDEV)", __LINE__); return find.crid;}static const char *crfind(int crid){ static struct crypt_find_op find; bzero(&find, sizeof(find)); find.crid = crid; if (ioctl(devcrypto(), CRIOFINDDEV, &find) == -1) err(1, "line %d:ioctl(CIOCFINDDEV): crid %d", __LINE__, crid); return find.name;}static intcrget(void){ int fd; if (ioctl(devcrypto(), CRIOGET, &fd) == -1) err(1, "line %d:ioctl(CRIOGET)", __LINE__); if (fcntl(fd, F_SETFD, 1) == -1) err(1, "fcntl(F_SETFD) (crget)"); return fd;}static charrdigit(void){#if 1 const char a[] = { 0x10,0x54,0x11,0x48,0x45,0x12,0x4f,0x13,0x49,0x53,0x14,0x41, 0x15,0x16,0x4e,0x55,0x54,0x17,0x18,0x4a,0x4f,0x42,0x19,0x01 }; return 0x20+a[random()%N(a)];#else static unsigned char c = 0; return (c++);#endif}static voidruntest(struct alg *alg, int count, int size, u_long cmd, struct timeval *tv){ int i, fd = crget(); struct timeval start, stop; char *cleartext = NULL, *ciphertext = NULL, *originaltext = NULL; struct session2_op sop; struct crypt_op cop; char iv[MAX_IV_SIZE]; bzero(&sop, sizeof(sop)); if (!alg->ishash) { sop.keylen = (alg->minkeylen + alg->maxkeylen)/2; sop.key = (char *) malloc(sop.keylen); if (sop.key == NULL) err(1, "malloc (key)"); for (i = 0; i < sop.keylen; i++) sop.key[i] = rdigit(); sop.cipher = alg->code; if (swap_key) swap_buf(sop.key, sop.keylen); } else { sop.mackeylen = (alg->minkeylen + alg->maxkeylen)/2; sop.mackey = (char *) malloc(sop.mackeylen); if (sop.mackey == NULL) err(1, "malloc (mac)"); for (i = 0; i < sop.mackeylen; i++) sop.mackey[i] = rdigit(); sop.mac = alg->code; if (swap_key) swap_buf(sop.mackey, sop.mackeylen); } sop.crid = crid; if (verbose) printf(" crid = %x\n", crid); if (ioctl(fd, cmd, &sop) < 0) { if (cmd == CIOCGSESSION || cmd == CIOCGSESSION2) { close(fd); if (verbose) { printf("cipher %s", alg->name); if (alg->ishash) printf(" mackeylen %u\n", sop.mackeylen); else printf(" keylen %u\n", sop.keylen); perror("CIOCGSESSION"); } /* hardware doesn't support algorithm; skip it */ return; } printf("cipher %s keylen %u mackeylen %u\n", alg->name, sop.keylen, sop.mackeylen); err(1, "CIOCGSESSION"); } originaltext = (char *)malloc((alg->hashsize ? 2 : 3)*size + alg->hashsize); if (originaltext == NULL) err(1, "malloc (text)"); cleartext = originaltext+size; ciphertext = cleartext+size; for (i = 0; i < size; i++) cleartext[i] = rdigit(); memcpy(originaltext, cleartext, size); for (i = 0; i < N(iv); i++) iv[i] = rdigit(); if (verbose) { printf("alg = %s\n", alg->name); printf("session = 0x%x\n", sop.ses); printf("device = %s\n", crfind(sop.crid)); printf("count = %d, size = %d\n", count, size); if (!alg->ishash) { printf("iv:"); hexdump(iv, sizeof iv); } printf("cleartext:"); hexdump(cleartext, MIN(size, CHUNK)); } gettimeofday(&start, NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -