Re: comparison of the AF_ALG interface with the /dev/crypto

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Nikos Mavrogiannopoulos <nmav@xxxxxxxxxx>
Date: Sun, 28 Aug 2011 15:17:00 +0200

> The benchmark idea was to test the speed of initialization, encryption
> and deinitiation, as well as the encryption speed alone. These are the
> most common use cases of the frameworks (i.e. how they would be used
> by a cryptographic library).

Be sure to use splice() with AF_ALG for maximum performance.

For example, see the test program below.  You'll need to replace
"8192" with whatever the page size is on your cpu.

--------------------
#include <fcntl.h>
#include <openssl/aes.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <linux/types.h>

#define AF_ALG 38
#define SOL_ALG 279

#define SPLICE_F_GIFT	(0x08)	/* pages passed in are a gift */

struct sockaddr_alg {
	__u16	salg_family;
	__u8	salg_type[14];
	__u32	salg_feat;
	__u32	salg_mask;
	__u8	salg_name[64];
};

struct af_alg_iv {
	__u32	ivlen;
	__u8	iv[0];
};

/* Socket options */
#define ALG_SET_KEY			1
#define ALG_SET_IV			2
#define ALG_SET_OP			3

/* Operations */
#define ALG_OP_DECRYPT			0
#define ALG_OP_ENCRYPT			1

static char buf[8192] __attribute__((__aligned__(8192)));

static void crypt_ssl(const char *key, char *iv, int i)
{
	AES_KEY akey;

	AES_set_encrypt_key(key, 128, &akey);

	while (i--)
		AES_cbc_encrypt(buf, buf, 8192, &akey, iv, 1);
}

static void crypt_kernel(const char *key, char *oiv, int i)
{
	int opfd;
	int tfmfd;
	struct sockaddr_alg sa = {
		.salg_family = AF_ALG,
		.salg_type = "skcipher",
		.salg_name = "cbc(aes)"
	};
	struct msghdr msg = {};
	struct cmsghdr *cmsg;
	char cbuf[CMSG_SPACE(4) + CMSG_SPACE(20)] = {};
	struct aes_iv {
		__u32 len;
		__u8 iv[16];
	} *iv;
	struct iovec iov;
	int pipes[2];

	pipe(pipes);

	tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0);

	bind(tfmfd, (struct sockaddr *)&sa, sizeof(sa));

	setsockopt(tfmfd, SOL_ALG, ALG_SET_KEY, key, 16);

	opfd = accept(tfmfd, NULL, 0);

	msg.msg_control = cbuf;
	msg.msg_controllen = sizeof(cbuf);

	cmsg = CMSG_FIRSTHDR(&msg);
	cmsg->cmsg_level = SOL_ALG;
	cmsg->cmsg_type = ALG_SET_OP;
	cmsg->cmsg_len = CMSG_LEN(4);
	*(__u32 *)CMSG_DATA(cmsg) = ALG_OP_ENCRYPT;

	cmsg = CMSG_NXTHDR(&msg, cmsg);
	cmsg->cmsg_level = SOL_ALG;
	cmsg->cmsg_type = ALG_SET_IV;
	cmsg->cmsg_len = CMSG_LEN(20);
	iv = (void *)CMSG_DATA(cmsg);
	iv->len = 16;
	memcpy(iv->iv, oiv, 16);

	iov.iov_base = buf;
	iov.iov_len = 8192;

	msg.msg_iovlen = 0;
	msg.msg_flags = MSG_MORE;

	while (i--) {
		sendmsg(opfd, &msg, 0);
		vmsplice(pipes[1], &iov, 1, SPLICE_F_GIFT);
		splice(pipes[0], NULL, opfd, NULL, 8192, 0);
		read(opfd, buf, 8192);
	}

	close(opfd);
	close(tfmfd);
	close(pipes[0]);
	close(pipes[1]);
}

int main(int argc, char **argv)
{
	int i;

	const char key[16] =
		"\x06\xa9\x21\x40\x36\xb8\xa1\x5b"
		"\x51\x2e\x03\xd5\x34\x12\x00\x06";
	char iv[16] = 
		"\x3d\xaf\xba\x42\x9d\x9e\xb4\x30"
		"\xb4\x22\xda\x80\x2c\x9f\xac\x41";
	
	memcpy(buf, "Single block msg", 16);

	if (argc > 1)
		crypt_ssl(key, iv, 1024 * 1024);
	else
		crypt_kernel(key, iv, 1024 * 1024);

	for (i = 0; i < 8192; i++) {
		printf("%02x", (unsigned char)buf[i]);
	}
	printf("\n");

	return 0;
}
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]

  Powered by Linux