--- .gitignore | 3 + examples/Makefile | 9 +- examples/async_cipher.c | 281 +++++++++++++++++++++++++++++++++++++++++++++ examples/async_hmac.c | 292 +++++++++++++++++++++++++++++++++++++++++++++++ examples/async_speed.c | 197 +++++++++++++++++++++++++++++++ examples/testhelper.h | 57 +++++++++ 6 files changed, 837 insertions(+), 2 deletions(-) create mode 100644 examples/async_cipher.c create mode 100644 examples/async_hmac.c create mode 100644 examples/async_speed.c create mode 100644 examples/testhelper.h
diff --git a/.gitignore b/.gitignore index 8b6dce9..893869a 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,9 @@ Module.symvers *.o *.mod.c modules.order +examples/async_cipher +examples/async_hmac +examples/async_speed examples/cipher examples/hmac examples/speed diff --git a/examples/Makefile b/examples/Makefile index 937eb6d..ff88d54 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,13 +1,18 @@ KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build -hostprogs := cipher hmac speed +hostprogs := cipher hmac speed async_cipher async_hmac async_speed example-cipher-objs := cipher.o example-hmac-objs := hmac.o example-speed-objs := speed.c +example-async-cipher-objs := async_cipher.o +example-async-hmac-objs := async_hmac.o +example-async-speed-objs := async_speed.o check: $(hostprogs) ./cipher ./hmac + ./async_cipher + ./async_hmac clean: - rm -f *.o *~ hmac cipher speed + rm -f *.o *~ hmac cipher speed async_hmac async_cipher async_speed diff --git a/examples/async_cipher.c b/examples/async_cipher.c new file mode 100644 index 0000000..aae9379 --- /dev/null +++ b/examples/async_cipher.c @@ -0,0 +1,281 @@ +/* + * Demo on how to use /dev/crypto device for ciphering. + * + * Placed under public domain. + * + */ +#include <poll.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> + +#include <sys/ioctl.h> +#include <crypto/cryptodev.h> + +#include "testhelper.h" + +#define DATA_SIZE 8*1024 +#define BLOCK_SIZE 16 +#define KEY_SIZE 16 + +static int +test_crypto(int cfd) +{ + char plaintext[DATA_SIZE]; + char ciphertext[DATA_SIZE]; + char iv[BLOCK_SIZE]; + char key[KEY_SIZE]; + + struct session_op sess; + struct crypt_op cryp; + + printf("running %s\n", __func__); + + memset(&sess, 0, sizeof(sess)); + memset(&cryp, 0, sizeof(cryp)); + + memset(plaintext, 0x15, sizeof(plaintext)); + memset(key, 0x33, sizeof(key)); + memset(iv, 0x03, sizeof(iv)); + + /* Get crypto session for AES128 */ + sess.cipher = CRYPTO_AES_CBC; + sess.keylen = KEY_SIZE; + sess.key = key; + if (ioctl(cfd, CIOCGSESSION, &sess)) { + perror("ioctl(CIOCGSESSION)"); + return 1; + } + + printf("%s: got the session\n", __func__); + + + /* Encrypt data.in to data.encrypted */ + cryp.ses = sess.ses; + cryp.len = sizeof(plaintext); + cryp.src = plaintext; + cryp.dst = ciphertext; + cryp.iv = iv; + cryp.op = COP_ENCRYPT; + + DO_OR_DIE(do_async_crypt(cfd, &cryp), 0); + DO_OR_DIE(do_async_fetch(cfd, &cryp), 0); + + printf("%s: data encrypted\n", __func__); + + if (ioctl(cfd, CIOCFSESSION, &sess.ses)) { + perror("ioctl(CIOCFSESSION)"); + return 1; + } + printf("%s: session finished\n", __func__); + + if (ioctl(cfd, CIOCGSESSION, &sess)) { + perror("ioctl(CIOCGSESSION)"); + return 1; + } + printf("%s: got new session\n", __func__); + + /* Decrypt data.encrypted to data.decrypted */ + cryp.ses = sess.ses; + cryp.len = sizeof(plaintext); + cryp.src = ciphertext; + cryp.dst = ciphertext; + cryp.iv = iv; + cryp.op = COP_DECRYPT; + + DO_OR_DIE(do_async_crypt(cfd, &cryp), 0); + DO_OR_DIE(do_async_fetch(cfd, &cryp), 0); + + printf("%s: data encrypted\n", __func__); + + /* Verify the result */ + if (memcmp(plaintext, ciphertext, sizeof(plaintext)) != 0) { + fprintf(stderr, + "FAIL: Decrypted data are different from the input data.\n"); + return 1; + } else + printf("Test passed\n"); + + /* Finish crypto session */ + if (ioctl(cfd, CIOCFSESSION, &sess.ses)) { + perror("ioctl(CIOCFSESSION)"); + return 1; + } + + return 0; +} + +static int test_aes(int cfd) +{ + char plaintext1[BLOCK_SIZE]; + char ciphertext1[BLOCK_SIZE] = { 0xdf, 0x55, 0x6a, 0x33, 0x43, 0x8d, 0xb8, 0x7b, 0xc4, 0x1b, 0x17, 0x52, 0xc5, 0x5e, 0x5e, 0x49 }; + char iv1[BLOCK_SIZE]; + char key1[KEY_SIZE] = { 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + char plaintext2[BLOCK_SIZE] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00 }; + char ciphertext2[BLOCK_SIZE] = { 0xb7, 0x97, 0x2b, 0x39, 0x41, 0xc4, 0x4b, 0x90, 0xaf, 0xa7, 0xb2, 0x64, 0xbf, 0xba, 0x73, 0x87 }; + char iv2[BLOCK_SIZE]; + char key2[KEY_SIZE]; + + struct session_op sess1, sess2; + struct crypt_op cryp1, cryp2; + + printf("running %s\n", __func__); + + memset(&sess1, 0, sizeof(sess1)); + memset(&sess2, 0, sizeof(sess2)); + memset(&cryp1, 0, sizeof(cryp1)); + memset(&cryp2, 0, sizeof(cryp2)); + + memset(plaintext1, 0x0, sizeof(plaintext1)); + memset(iv1, 0x0, sizeof(iv1)); + + /* Get crypto session for AES128 */ + sess1.cipher = CRYPTO_AES_CBC; + sess1.keylen = KEY_SIZE; + sess1.key = key1; + if (ioctl(cfd, CIOCGSESSION, &sess1)) { + perror("ioctl(CIOCGSESSION)"); + return 1; + } + + memset(key2, 0x0, sizeof(key2)); + + /* Get second crypto session for AES128 */ + sess2.cipher = CRYPTO_AES_CBC; + sess2.keylen = KEY_SIZE; + sess2.key = key2; + if (ioctl(cfd, CIOCGSESSION, &sess2)) { + perror("ioctl(CIOCGSESSION)"); + return 1; + } + + /* Encrypt data.in to data.encrypted */ + cryp1.ses = sess1.ses; + cryp1.len = sizeof(plaintext1); + cryp1.src = plaintext1; + cryp1.dst = plaintext1; + cryp1.iv = iv1; + cryp1.op = COP_ENCRYPT; + + DO_OR_DIE(do_async_crypt(cfd, &cryp1), 0); + printf("cryp1 written out\n"); + + memset(iv2, 0x0, sizeof(iv2)); + + /* Encrypt data.in to data.encrypted */ + cryp2.ses = sess2.ses; + cryp2.len = sizeof(plaintext2); + cryp2.src = plaintext2; + cryp2.dst = plaintext2; + cryp2.iv = iv2; + cryp2.op = COP_ENCRYPT; + + DO_OR_DIE(do_async_crypt(cfd, &cryp2), 0); + printf("cryp2 written out\n"); + + DO_OR_DIE(do_async_fetch(cfd, &cryp1), 0); + DO_OR_DIE(do_async_fetch(cfd, &cryp2), 0); + printf("cryp1 + cryp2 successfully read\n"); + + /* Verify the result */ + if (memcmp(plaintext1, ciphertext1, sizeof(plaintext1)) != 0) { + int i; + fprintf(stderr, + "FAIL: Decrypted data are different from the input data.\n"); + printf("cipher text should be:\t"); + for (i = 0; i < BLOCK_SIZE; i++) { + printf("%02x ", (unsigned char)ciphertext1[i]); + } + printf("\nbut really is:\t\t"); + for (i = 0; i < BLOCK_SIZE; i++) { + printf("%02x ", (unsigned char)plaintext1[i]); + } + printf("\n"); + return 1; + } else { + printf("result 1 passed\n"); + } + + /* Test 2 */ + + /* Verify the result */ + if (memcmp(plaintext2, ciphertext2, sizeof(plaintext2)) != 0) { + int i; + fprintf(stderr, + "FAIL: Decrypted data are different from the input data.\n"); + printf("cipher text should be:\t"); + for (i = 0; i < BLOCK_SIZE; i++) { + printf("%02x ", (unsigned char)ciphertext2[i]); + } + printf("\nbut really is:\t\t"); + for (i = 0; i < BLOCK_SIZE; i++) { + printf("%02x ", (unsigned char)plaintext2[i]); + } + printf("\n"); + return 1; + } else { + printf("result 2 passed\n"); + } + + printf("AES Test passed\n"); + + /* Finish crypto session */ + if (ioctl(cfd, CIOCFSESSION, &sess1.ses)) { + perror("ioctl(CIOCFSESSION)"); + return 1; + } + if (ioctl(cfd, CIOCFSESSION, &sess2.ses)) { + perror("ioctl(CIOCFSESSION)"); + return 1; + } + + return 0; +} + +int +main() +{ + int fd = -1, cfd = -1; + + /* Open the crypto device */ + fd = open("/dev/crypto", O_RDWR, 0); + if (fd < 0) { + perror("open(/dev/crypto)"); + return 1; + } + + /* Clone file descriptor */ + if (ioctl(fd, CRIOGET, &cfd)) { + perror("ioctl(CRIOGET)"); + return 1; + } + + /* Set close-on-exec (not really neede here) */ + if (fcntl(cfd, F_SETFD, 1) == -1) { + perror("fcntl(F_SETFD)"); + return 1; + } + + /* Run the test itself */ + if (test_aes(cfd)) + return 1; + + if (test_crypto(cfd)) + return 1; + + /* Close cloned descriptor */ + if (close(cfd)) { + perror("close(cfd)"); + return 1; + } + + /* Close the original descriptor */ + if (close(fd)) { + perror("close(fd)"); + return 1; + } + + return 0; +} + diff --git a/examples/async_hmac.c b/examples/async_hmac.c new file mode 100644 index 0000000..be02752 --- /dev/null +++ b/examples/async_hmac.c @@ -0,0 +1,292 @@ +/* + * Demo on how to use /dev/crypto device for HMAC. + * + * Placed under public domain. + * + */ +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <poll.h> +#include <stdint.h> + +#include <sys/ioctl.h> +#include <crypto/cryptodev.h> + +#include "testhelper.h" + +#define DATA_SIZE 4096 +#define BLOCK_SIZE 16 +#define KEY_SIZE 16 +#define SHA1_HASH_LEN 20 + +static int +test_crypto(int cfd) +{ + struct { + uint8_t in[DATA_SIZE], + encrypted[DATA_SIZE], + decrypted[DATA_SIZE], + iv[BLOCK_SIZE], + key[KEY_SIZE]; + } data; + struct session_op sess; + struct crypt_op cryp; + uint8_t mac[AALG_MAX_RESULT_LEN]; + uint8_t oldmac[AALG_MAX_RESULT_LEN]; + uint8_t md5_hmac_out[] = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38"; + uint8_t sha1_out[] = "\x8f\x82\x03\x94\xf9\x53\x35\x18\x20\x45\xda\x24\xf3\x4d\xe5\x2b\xf8\xbc\x34\x32"; + int i; + + memset(&sess, 0, sizeof(sess)); + memset(&cryp, 0, sizeof(cryp)); + + /* Use the garbage that is on the stack :-) */ + /* memset(&data, 0, sizeof(data)); */ + + /* SHA1 plain test */ + memset(mac, 0, sizeof(mac)); + + sess.cipher = 0; + sess.mac = CRYPTO_SHA1; + if (ioctl(cfd, CIOCGSESSION, &sess)) { + perror("ioctl(CIOCGSESSION)"); + return 1; + } + + cryp.ses = sess.ses; + cryp.len = sizeof("what do ya want for nothing?")-1; + cryp.src = "what do ya want for nothing?"; + cryp.mac = mac; + cryp.op = COP_ENCRYPT; + + DO_OR_DIE(do_async_crypt(cfd, &cryp), 0); + DO_OR_DIE(do_async_fetch(cfd, &cryp), 0); + + if (memcmp(mac, sha1_out, 20)!=0) { + printf("mac: "); + for (i=0;i<SHA1_HASH_LEN;i++) { + printf("%.2x", (uint8_t)mac[i]); + } + puts("\n"); + fprintf(stderr, "HASH test 1: failed\n"); + } else { + fprintf(stderr, "HASH test 1: passed\n"); + } + + if (ioctl(cfd, CIOCFSESSION, &sess.ses)) { + perror("ioctl(CIOCFSESSION)"); + return 1; + } + + /* MD5-HMAC test */ + memset(mac, 0, sizeof(mac)); + + sess.cipher = 0; + sess.mackey = (uint8_t*)"Jefe"; + sess.mackeylen = 4; + sess.mac = CRYPTO_MD5_HMAC; + if (ioctl(cfd, CIOCGSESSION, &sess)) { + perror("ioctl(CIOCGSESSION)"); + return 1; + } + + cryp.ses = sess.ses; + cryp.len = sizeof("what do ya want for nothing?")-1; + cryp.src = "what do ya want for nothing?"; + cryp.mac = mac; + cryp.op = COP_ENCRYPT; + + DO_OR_DIE(do_async_crypt(cfd, &cryp), 0); + DO_OR_DIE(do_async_fetch(cfd, &cryp), 0); + + if (memcmp(mac, md5_hmac_out, 16)!=0) { + printf("mac: "); + for (i=0;i<SHA1_HASH_LEN;i++) { + printf("%.2x", (uint8_t)mac[i]); + } + puts("\n"); + fprintf(stderr, "HMAC test 1: failed\n"); + } else { + fprintf(stderr, "HMAC test 1: passed\n"); + } + + if (ioctl(cfd, CIOCFSESSION, &sess.ses)) { + perror("ioctl(CIOCFSESSION)"); + return 1; + } + + /* Hash and encryption in one step test */ + sess.cipher = CRYPTO_AES_CBC; + sess.mac = CRYPTO_SHA1_HMAC; + sess.keylen = KEY_SIZE; + sess.key = data.key; + sess.mackeylen = 16; + sess.mackey = (uint8_t*)"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"; + if (ioctl(cfd, CIOCGSESSION, &sess)) { + perror("ioctl(CIOCGSESSION)"); + return 1; + } + + /* Encrypt data.in to data.encrypted */ + cryp.ses = sess.ses; + cryp.len = sizeof(data.in); + cryp.src = data.in; + cryp.dst = data.encrypted; + cryp.iv = data.iv; + cryp.mac = mac; + cryp.op = COP_ENCRYPT; + + DO_OR_DIE(do_async_crypt(cfd, &cryp), 0); + DO_OR_DIE(do_async_fetch(cfd, &cryp), 0); + + memcpy(oldmac, mac, sizeof(mac)); + + /* Decrypt data.encrypted to data.decrypted */ + cryp.src = data.encrypted; + cryp.dst = data.decrypted; + cryp.op = COP_DECRYPT; + + DO_OR_DIE(do_async_crypt(cfd, &cryp), 0); + DO_OR_DIE(do_async_fetch(cfd, &cryp), 0); + + /* Verify the result */ + if (memcmp(data.in, data.decrypted, sizeof(data.in)) != 0) { + fprintf(stderr, + "FAIL: Decrypted data are different from the input data.\n"); + return 1; + } else + printf("Crypt Test: passed\n"); + + if (memcmp(mac, oldmac, 20) != 0) { + fprintf(stderr, + "FAIL: Hash in decrypted data different than in encrypted.\n"); + return 1; + } else + printf("HMAC Test 2: passed\n"); + + /* Finish crypto session */ + if (ioctl(cfd, CIOCFSESSION, &sess.ses)) { + perror("ioctl(CIOCFSESSION)"); + return 1; + } + + return 0; +} + +static int +test_extras(int cfd) +{ + struct session_op sess; + struct crypt_op cryp; + uint8_t mac[AALG_MAX_RESULT_LEN]; + uint8_t oldmac[AALG_MAX_RESULT_LEN]; + uint8_t md5_hmac_out[] = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38"; + uint8_t sha1_out[] = "\x8f\x82\x03\x94\xf9\x53\x35\x18\x20\x45\xda\x24\xf3\x4d\xe5\x2b\xf8\xbc\x34\x32"; + int i; + + memset(&sess, 0, sizeof(sess)); + memset(&cryp, 0, sizeof(cryp)); + + /* Use the garbage that is on the stack :-) */ + /* memset(&data, 0, sizeof(data)); */ + + /* SHA1 plain test */ + memset(mac, 0, sizeof(mac)); + + sess.cipher = 0; + sess.mac = CRYPTO_SHA1; + if (ioctl(cfd, CIOCGSESSION, &sess)) { + perror("ioctl(CIOCGSESSION)"); + return 1; + } + + cryp.ses = sess.ses; + cryp.len = sizeof("what do")-1; + cryp.src = "what do"; + cryp.mac = mac; + cryp.op = COP_ENCRYPT; + cryp.flags = COP_FLAG_UPDATE; + + DO_OR_DIE(do_async_crypt(cfd, &cryp), 0); + DO_OR_DIE(do_async_fetch(cfd, &cryp), 0); + + cryp.ses = sess.ses; + cryp.len = sizeof(" ya want for nothing?")-1; + cryp.src = " ya want for nothing?"; + cryp.mac = mac; + cryp.op = COP_ENCRYPT; + cryp.flags = COP_FLAG_FINAL; + + DO_OR_DIE(do_async_crypt(cfd, &cryp), 0); + DO_OR_DIE(do_async_fetch(cfd, &cryp), 0); + + if (memcmp(mac, sha1_out, 20)!=0) { + printf("mac: "); + for (i=0;i<SHA1_HASH_LEN;i++) { + printf("%.2x", (uint8_t)mac[i]); + } + puts("\n"); + fprintf(stderr, "HASH test [update]: failed\n"); + } else { + fprintf(stderr, "HASH test [update]: passed\n"); + } + + memset(mac, 0, sizeof(mac)); + + /* Finish crypto session */ + if (ioctl(cfd, CIOCFSESSION, &sess.ses)) { + perror("ioctl(CIOCFSESSION)"); + return 1; + } + + return 0; +} + + +int +main() +{ + int fd = -1, cfd = -1; + + /* Open the crypto device */ + fd = open("/dev/crypto", O_RDWR, 0); + if (fd < 0) { + perror("open(/dev/crypto)"); + return 1; + } + + /* Clone file descriptor */ + if (ioctl(fd, CRIOGET, &cfd)) { + perror("ioctl(CRIOGET)"); + return 1; + } + + /* Set close-on-exec (not really neede here) */ + if (fcntl(cfd, F_SETFD, 1) == -1) { + perror("fcntl(F_SETFD)"); + return 1; + } + + /* Run the test itself */ + if (test_crypto(cfd)) + return 1; + + if (test_extras(cfd)) + return 1; + + /* Close cloned descriptor */ + if (close(cfd)) { + perror("close(cfd)"); + return 1; + } + + /* Close the original descriptor */ + if (close(fd)) { + perror("close(fd)"); + return 1; + } + + return 0; +} diff --git a/examples/async_speed.c b/examples/async_speed.c new file mode 100644 index 0000000..a288144 --- /dev/null +++ b/examples/async_speed.c @@ -0,0 +1,197 @@ +/* cryptodev_test - simple benchmark tool for cryptodev + * + * Copyright (C) 2010 by Phil Sutter <phil.sut...@viprinet.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <errno.h> +#include <fcntl.h> +#include <poll.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <sys/types.h> +#include <signal.h> +#include <crypto/cryptodev.h> + +static double udifftimeval(struct timeval start, struct timeval end) +{ + return (double)(end.tv_usec - start.tv_usec) + + (double)(end.tv_sec - start.tv_sec) * 1000 * 1000; +} + +static int must_finish = 0; +static struct pollfd pfd; + +static void alarm_handler(int signo) +{ + must_finish = 1; + pfd.events = POLLIN; +} + +static void value2human(double bytes, double time, double* data, double* speed,char* metric) +{ + if (bytes > 1000 && bytes < 1000*1000) { + *data = ((double)bytes)/1000; + *speed = *data/time; + strcpy(metric, "Kb"); + return; + } else if (bytes >= 1000*1000 && bytes < 1000*1000*1000) { + *data = ((double)bytes)/(1000*1000); + *speed = *data/time; + strcpy(metric, "Mb"); + return; + } else if (bytes >= 1000*1000*1000) { + *data = ((double)bytes)/(1000*1000*1000); + *speed = *data/time; + strcpy(metric, "Gb"); + return; + } else { + *data = (double)bytes; + *speed = *data/time; + strcpy(metric, "bytes"); + return; + } +} + + +int encrypt_data(struct session_op *sess, int fdc, int chunksize, int flags) +{ + struct crypt_op cop; + char *buffer[256], iv[32]; + static int val = 23; + struct timeval start, end; + double total = 0; + double secs, ddata, dspeed; + char metric[16]; + int rc, wqueue = 0, bufidx = 0; + + memset(iv, 0x23, 32); + + printf("\tEncrypting in chunks of %d bytes: ", chunksize); + fflush(stdout); + + for (rc = 0; rc < 256; rc++) { + buffer[rc] = malloc(chunksize); + memset(buffer[rc], val++, chunksize); + } + pfd.fd = fdc; + pfd.events = POLLOUT | POLLIN; + + must_finish = 0; + alarm(5); + + gettimeofday(&start, NULL); + do { + if ((rc = poll(&pfd, 1, 100)) < 0) { + if (errno & (ERESTART | EINTR)) + continue; + fprintf(stderr, "errno = %d ", errno); + perror("poll()"); + return 1; + } + + if (pfd.revents & POLLOUT) { + memset(&cop, 0, sizeof(cop)); + cop.ses = sess->ses; + cop.len = chunksize; + cop.iv = (unsigned char *)iv; + cop.op = COP_ENCRYPT; + cop.flags = flags; + cop.src = cop.dst = (unsigned char *)buffer[bufidx]; + bufidx = (bufidx + 1) % 256; + + if (ioctl(fdc, CIOCASYNCCRYPT, &cop)) { + perror("ioctl(CIOCASYNCCRYPT)"); + return 1; + } + wqueue++; + } + if (pfd.revents & POLLIN) { + if (ioctl(fdc, CIOCASYNCFETCH, &cop)) { + perror("ioctl(CIOCASYNCFETCH)"); + return 1; + } + wqueue--; + total += cop.len; + } + } while(!must_finish || wqueue); + gettimeofday(&end, NULL); + + secs = udifftimeval(start, end)/ 1000000.0; + + value2human(total, secs, &ddata, &dspeed, metric); + printf ("done. %.2f %s in %.2f secs: ", ddata, metric, secs); + printf ("%.2f %s/sec\n", dspeed, metric); + + for (rc = 0; rc < 256; rc++) + free(buffer[rc]); + return 0; +} + +int main(void) +{ + int fd, i, fdc = -1; + struct session_op sess; + char keybuf[32]; + + signal(SIGALRM, alarm_handler); + + if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) { + perror("open()"); + return 1; + } + if (ioctl(fd, CRIOGET, &fdc)) { + perror("ioctl(CRIOGET)"); + return 1; + } + + fprintf(stderr, "Testing NULL cipher: \n"); + memset(&sess, 0, sizeof(sess)); + sess.cipher = CRYPTO_NULL; + sess.keylen = 0; + sess.key = (unsigned char *)keybuf; + if (ioctl(fdc, CIOCGSESSION, &sess)) { + perror("ioctl(CIOCGSESSION)"); + return 1; + } + + for (i = 256; i <= (64 * 4096); i *= 2) { + if (encrypt_data(&sess, fdc, i, 0)) + break; + } + + fprintf(stderr, "\nTesting AES-128-CBC cipher: \n"); + memset(&sess, 0, sizeof(sess)); + sess.cipher = CRYPTO_AES_CBC; + sess.keylen = 16; + memset(keybuf, 0x42, 16); + sess.key = (unsigned char *)keybuf; + if (ioctl(fdc, CIOCGSESSION, &sess)) { + perror("ioctl(CIOCGSESSION)"); + return 1; + } + + for (i = 256; i <= (64 * 1024); i *= 2) { + if (encrypt_data(&sess, fdc, i, 0)) + break; + } + + close(fdc); + close(fd); + return 0; +} diff --git a/examples/testhelper.h b/examples/testhelper.h new file mode 100644 index 0000000..ea0b100 --- /dev/null +++ b/examples/testhelper.h @@ -0,0 +1,57 @@ +/* + * Some helper stuff shared between the sample programs. + */ +#ifndef _TESTHELPER_H +#define _TESTHELPER_H + +/* poll until POLLOUT, then call CIOCASYNCCRYPT */ +inline int do_async_crypt(int cfd, struct crypt_op *cryp) +{ + struct pollfd pfd; + + pfd.fd = cfd; + pfd.events = POLLOUT; + + if (poll(&pfd, 1, -1) < 1) { + perror("poll()"); + return 1; + } + + if (ioctl(cfd, CIOCASYNCCRYPT, cryp)) { + perror("ioctl(CIOCCRYPT)"); + return 1; + } + return 0; +} + +/* poll until POLLIN, then call CIOCASYNCFETCH */ +inline int do_async_fetch(int cfd, struct crypt_op *cryp) +{ + struct pollfd pfd; + + pfd.fd = cfd; + pfd.events = POLLIN; + + if (poll(&pfd, 1, -1) < 1) { + perror("poll()"); + return 1; + } + + if (ioctl(cfd, CIOCASYNCFETCH, cryp)) { + perror("ioctl(CIOCCRYPT)"); + return 1; + } + return 0; +} + +/* Check return value of stmt for identity with goodval. If they + * don't match, call return with the value of stmt. */ +#define DO_OR_DIE(stmt, goodval) { \ + int __rc_val; \ + if ((__rc_val = stmt) != goodval) { \ + perror("DO_OR_DIE(" #stmt "," #goodval ")"); \ + return __rc_val; \ + } \ +} + +#endif /* _TESTHELPER_H */ -- 1.7.2.2 _______________________________________________ Cryptodev-linux-devel mailing list Cryptodev-linux-devel@gna.org https://mail.gna.org/listinfo/cryptodev-linux-devel