summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/tools/README1
-rw-r--r--tools/tools/crypto/Makefile11
-rw-r--r--tools/tools/crypto/README44
-rw-r--r--tools/tools/crypto/cryptotest.c293
4 files changed, 349 insertions, 0 deletions
diff --git a/tools/tools/README b/tools/tools/README
index 1954550..a924b49 100644
--- a/tools/tools/README
+++ b/tools/tools/README
@@ -9,6 +9,7 @@ Please make a subdir per program, and add a brief description to this file.
commitsdb A tool for reconstructing commit history using md5
checksums of the commit logs.
+crypto Exercise the crypto framework through /dev/crypto
editing Editor modes and the like to help editing FreeBSD code.
epfe Extract printing filter examples from printing.sgml.
find-sb Scan a disk for possible filesystem superblocks.
diff --git a/tools/tools/crypto/Makefile b/tools/tools/crypto/Makefile
new file mode 100644
index 0000000..e592761
--- /dev/null
+++ b/tools/tools/crypto/Makefile
@@ -0,0 +1,11 @@
+# $FreeBSD$
+
+ALL= cryptotest
+
+all: ${ALL}
+
+cryptotest: cryptotest.c
+ ${CC} -o cryptotest cryptotest.c
+
+clean:
+ rm -f ${ALL} core a.out
diff --git a/tools/tools/crypto/README b/tools/tools/crypto/README
new file mode 100644
index 0000000..16b6bdb
--- /dev/null
+++ b/tools/tools/crypto/README
@@ -0,0 +1,44 @@
+$FreeBSD$
+
+The cryptotest program repeatedly encrypts and decrypts a buffer
+with the built-in iv and key, using hardware crypto. At the end,
+it computes the data rate achieved. Operations are carried out by
+making ioctl calls to /dev/crypto.
+
+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.
+
+A sample run is:
+
+ 0.129 sec, 2048 des crypts, 8 bytes, 127120 byte/sec, 1.0 Mb/sec
+ 0.129 sec, 2048 des crypts, 16 bytes, 253915 byte/sec, 1.9 Mb/sec
+ 0.129 sec, 2048 des crypts, 32 bytes, 508942 byte/sec, 3.9 Mb/sec
+ 0.128 sec, 2048 des crypts, 64 bytes, 1020135 byte/sec, 7.8 Mb/sec
+ 0.134 sec, 2048 des crypts, 128 bytes, 1954869 byte/sec, 14.9 Mb/sec
+ 0.142 sec, 2048 des crypts, 256 bytes, 3698107 byte/sec, 28.2 Mb/sec
+ 0.190 sec, 2048 des crypts, 1024 bytes, 11037700 byte/sec, 84.2 Mb/sec
+ 0.264 sec, 2048 des crypts, 2048 bytes, 15891127 byte/sec, 121.2 Mb/sec
+ 0.403 sec, 2048 des crypts, 4096 bytes, 20828998 byte/sec, 158.9 Mb/sec
+ 0.687 sec, 2048 des crypts, 8192 bytes, 24426602 byte/sec, 186.4 Mb/sec
+ 0.129 sec, 2048 3des crypts, 8 bytes, 127321 byte/sec, 1.0 Mb/sec
+ 0.131 sec, 2048 3des crypts, 16 bytes, 249773 byte/sec, 1.9 Mb/sec
+ 0.128 sec, 2048 3des crypts, 32 bytes, 512304 byte/sec, 3.9 Mb/sec
+ 0.128 sec, 2048 3des crypts, 64 bytes, 1021685 byte/sec, 7.8 Mb/sec
+ 0.132 sec, 2048 3des crypts, 128 bytes, 1986511 byte/sec, 15.2 Mb/sec
+ 0.142 sec, 2048 3des crypts, 256 bytes, 3695005 byte/sec, 28.2 Mb/sec
+ 0.190 sec, 2048 3des crypts, 1024 bytes, 11024876 byte/sec, 84.1 Mb/sec
+ 0.264 sec, 2048 3des crypts, 2048 bytes, 15887997 byte/sec, 121.2 Mb/sec
+ 0.402 sec, 2048 3des crypts, 4096 bytes, 20850846 byte/sec, 159.1 Mb/sec
+ 0.689 sec, 2048 3des crypts, 8192 bytes, 24333532 byte/sec, 185.7 Mb/sec
+
+Expect ~400 Mb/s for a Broadcom 582x for 16K buffers on a reasonable
+CPU. Hifn 7811 parts top out at ~120 Mb/s. Performance depends
+heavily on memory and bus performance.
+
+This code originally came from openbsd; give them all the credit.
diff --git a/tools/tools/crypto/cryptotest.c b/tools/tools/crypto/cryptotest.c
new file mode 100644
index 0000000..70008b2
--- /dev/null
+++ b/tools/tools/crypto/cryptotest.c
@@ -0,0 +1,293 @@
+/* $FreeBSD$ */
+
+/*
+ * This program repeatedly encrypts and decrypts a buffer with the built-in
+ * iv and key, using hardware crypto. At the end, it computes the data rate
+ * achieved. invoke with the number of times to encrypt and the buffer size.
+ *
+ * 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.
+ *
+ * Expect ~400 Mb/s for a Broadcom 582x for 16K buffers on a reasonable CPU.
+ * Hifn 7811 parts top out at ~110 Mb/s.
+ *
+ * This code originally came from openbsd; give them all the credit.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <crypto/cryptodev.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.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 cryptodev_fd;
+int fd;
+struct session_op session;
+struct crypt_op cryptop;
+char iv[8] = "00000000";
+int verbose = 0;
+
+struct alg {
+ const char* name;
+ int blocksize;
+ int minkeylen;
+ int maxkeylen;
+ int code;
+} algorithms[] = {
+ { "null", 8, 1, 256, CRYPTO_NULL_CBC },
+ { "des", 8, 8, 8, CRYPTO_DES_CBC },
+ { "3des", 8, 24, 24, CRYPTO_3DES_CBC },
+ { "blf", 8, 5, 56, CRYPTO_BLF_CBC },
+ { "cast", 8, 5, 16, CRYPTO_CAST_CBC },
+ { "skj", 8, 10, 10, CRYPTO_SKIPJACK_CBC },
+ { "aes", 16, 8, 32, CRYPTO_RIJNDAEL128_CBC },
+#ifdef notdef
+ { "arc4", 8, 1, 32, CRYPTO_ARC4 },
+#endif
+};
+
+static void
+usage(const char* cmd)
+{
+ printf("usage: %s [-z] [-s] [-v] [-a algorithm] [count] [size ...]\n",
+ cmd);
+ printf("where algorithm is one of:\n");
+ printf(" des 3des (default) blowfish cast skipjack\n");
+ printf(" rijndael arc4\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");
+ 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 void
+runtest(struct alg *alg, int count, int size, int cmd)
+{
+ int i;
+ struct timeval start, stop, dt;
+ char *cleartext, *ciphertext;
+ double t;
+
+ if (size % alg->blocksize) {
+ if (verbose)
+ printf("skipping blocksize %u 'cuz not a multiple of "
+ "%s blocksize %u\n",
+ size, alg->name, alg->blocksize);
+ return;
+ }
+
+ if (ioctl(cryptodev_fd,CRIOGET,&fd) == -1)
+ err(1, "CRIOGET failed");
+
+ session.mac = 0;
+ session.keylen = (alg->minkeylen + alg->maxkeylen)/2;
+ session.key = (char *) malloc(session.keylen);
+ if (session.key == NULL)
+ err(1, "malloc (key)");
+ for (i = 0; i < session.keylen; i++)
+ session.key[i] = '0' + (i%10);
+ session.cipher = alg->code;
+ if (ioctl(fd, cmd, &session) == -1) {
+ if (cmd == CIOCGSESSION) {
+ close(fd);
+ /* hardware doesn't support algorithm; skip it */
+ return;
+ }
+ printf("cipher %s keylen %u\n", alg->name, session.keylen);
+ err(1, "CIOCGSESSION failed");
+ }
+
+ if ((cleartext = (char *)malloc(size)) == NULL)
+ err(1, "malloc (cleartext)");
+ if ((ciphertext = (char *)malloc(size)) == NULL)
+ err(1, "malloc (ciphertext)");
+ for (i = 0; i < size; i++)
+ cleartext[i] = 'a' + i%26;
+
+ if (verbose) {
+ printf("session = 0x%x\n", session.ses);
+ printf("count = %d, size = %d\n", count, size);
+ cryptop.ses = session.ses;
+ printf("iv:");
+ hexdump(iv, sizeof iv);
+ printf("cleartext:");
+ hexdump(cleartext, MIN(size, CHUNK));
+ }
+
+ gettimeofday(&start, NULL);
+ for (i = 0; i < count; i++) {
+ cryptop.op = COP_ENCRYPT;
+ cryptop.flags = 0;
+ cryptop.len = size;
+ cryptop.src = cleartext;
+ cryptop.dst = ciphertext;
+ cryptop.mac = 0;
+ cryptop.iv = iv;
+
+ if (ioctl(fd, CIOCCRYPT, &cryptop) == -1)
+ err(1, "CIOCCRYPT failed");
+
+ memset(cleartext, 'x', MIN(size, CHUNK));
+ cryptop.op = COP_DECRYPT;
+ cryptop.flags = 0;
+ cryptop.len = size;
+ cryptop.src = ciphertext;
+ cryptop.dst = cleartext;
+ cryptop.mac = 0;
+ cryptop.iv = iv;
+
+ if (ioctl(fd, CIOCCRYPT, &cryptop) == -1)
+ err(1, "CIOCCRYPT failed");
+ }
+ gettimeofday(&stop, NULL);
+
+ if (ioctl(fd, CIOCFSESSION, &session.ses) == -1)
+ perror("CIOCFSESSION");
+
+ if (verbose) {
+ printf("cleartext:");
+ hexdump(cleartext, MIN(size, CHUNK));
+ }
+ timersub(&stop, &start, &dt);
+ t = (((double)dt.tv_sec * 1000000 + dt.tv_usec) / 1000000);
+ printf("%6.3lf sec, %7d %6s crypts, %7d bytes, %8.0lf byte/sec, %7.1lf Mb/sec\n",
+ t, 2*count, alg->name, size, (double)2*count*size / t,
+ (double)2*count*size / t * 8 / 1024 / 1024);
+
+ free(ciphertext);
+ free(cleartext);
+
+ close(fd);
+}
+
+int
+main(int argc, char **argv)
+{
+ struct alg *alg = NULL;
+ int count = 1;
+ int sizes[128], nsizes = 0;
+ int cmd = CIOCGSESSION;
+ int testall = 0;
+ int i, ch;
+
+ while ((ch = getopt(argc, argv, "zsva:")) != -1) {
+ switch (ch) {
+#ifdef CIOCGSSESSION
+ case 's':
+ cmd = CIOCGSSESSION;
+ break;
+#endif
+ case 'v':
+ verbose++;
+ break;
+ case 'a':
+ alg = getalgbyname(optarg);
+ if (alg == NULL) {
+ if (streq(optarg, "rijndael"))
+ alg = getalgbyname("aes");
+ else
+ usage(argv[0]);
+ }
+ break;
+ case 'z':
+ testall = 1;
+ break;
+ default:
+ usage(argv[0]);
+ }
+ }
+ argc -= optind, argv += optind;
+ if (argc > 0)
+ count = atoi(argv[0]);
+ while (argc > 1) {
+ int s = atoi(argv[1]);
+ if (nsizes < N(sizes)) {
+ sizes[nsizes++] = s;
+ } else {
+ printf("Too many sizes, ignoring %u\n", s);
+ }
+ argc--, argv++;
+ }
+ if (nsizes == 0) {
+ sizes[nsizes++] = 8;
+ if (testall) {
+ while (sizes[nsizes-1] < 32768) {
+ sizes[nsizes] = sizes[nsizes-1]<<1;
+ nsizes++;
+ }
+ }
+ }
+
+ if ((cryptodev_fd = open("/dev/crypto",O_RDWR,0)) < 0)
+ err(1, "/dev/crypto");
+
+ if (testall) {
+ for (i = 0; i < N(algorithms); i++) {
+ int j;
+ alg = &algorithms[i];
+ for (j = 0; j < nsizes; j++)
+ runtest(alg, count, sizes[j], cmd);
+ }
+ } else {
+ if (alg == NULL)
+ alg = getalgbycode(CRYPTO_3DES_CBC);
+ for (i = 0; i < nsizes; i++)
+ runtest(alg, count, sizes[i], cmd);
+ }
+
+ return (0);
+}
+
+void hexdump(char *p, int n)
+{
+ int i;
+ for (i = 0; i < n; i++) {
+ if (i%16 == 0) {
+ if (i != 0) {
+ int j;
+ char *l = p-16;
+ printf(" |");
+ for (j = 0; j < 16; j++,l++)
+ printf("%c", (((*l)&0xff)>0x1f && ((*l)&0xff)<0x7f) ? (*l)&0xff : '.');
+ printf("|");
+ }
+ printf("\n%04x: ", i);
+ }
+ printf(" %02x", (int)(*p++)&0xff);
+ }
+ printf("\n");
+}
OpenPOWER on IntegriCloud