lkml.org 
[lkml]   [2011]   [Aug]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
SubjectRe: comparison of the AF_ALG interface with the /dev/crypto
From
From: Nikos Mavrogiannopoulos <nmav@gnutls.org>
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;
}


\
 
 \ /
  Last update: 2011-08-28 22:39    [W:0.364 / U:0.264 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site