Linux cryptographic layer development
 help / color / mirror / Atom feed
* OpenSSL patch to support Linux CryptoAPI.
@ 2008-08-08 18:31 Shasi Pulijala
  2008-08-08 21:09 ` Evgeniy Polyakov
  0 siblings, 1 reply; 6+ messages in thread
From: Shasi Pulijala @ 2008-08-08 18:31 UTC (permalink / raw)
  To: linux-crypto; +Cc: Loc Ho

[-- Attachment #1: Type: text/plain, Size: 248 bytes --]


Hi,
 
OpenSSL patch to support Linux CryptoAPI via CryptoDev interface. This patch depends on OCF patch to OpenSSL. After applying OCF patch to OpenSSL, apply this patch which will replace the lower interface into the Linux kernel.
 
-Shasi

[-- Attachment #2: 0001-Cryptodev-OpenSSL-Patch.txt --]
[-- Type: text/plain, Size: 16226 bytes --]

diff -Naur /user/openssl/openssl-0.9.8g/crypto/cryptodev.h /user/linux/openssl-0.9.8g/crypto/cryptodev.h
--- /user/openssl/openssl-0.9.8g/crypto/cryptodev.h 2008-08-07 15:57:14.007854000 -0700
+++ /user/linux/openssl-0.9.8g/crypto/cryptodev.h 2008-08-07 18:16:41.955477000 -0700
@@ -61,6 +61,8 @@
 #ifndef _CRYPTO_CRYPTO_H_
 #define _CRYPTO_CRYPTO_H_
 
+#include <linux/types.h>
+
 /* Some initial values */
 #define CRYPTO_DRIVERS_INITIAL	4
 #define CRYPTO_SW_SESSIONS	32
@@ -128,6 +130,7 @@
 
 /* Max size of data that can be processed */
 #define CRYPTO_MAX_DATA_LEN		64*1024 - 1
+#define CRYPTO_MAX_ALG_NAME		20
 
 
 #define CRYPTO_ALGORITHM_MIN		1
@@ -178,16 +181,13 @@
 #define CRYPTO_FLAG_SOFTWARE	0x02000000	/* software implementation */
 
 /* NB: deprecated */
-struct session_op {
-	u_int32_t	cipher;		/* ie. CRYPTO_DES_CBC */
-	u_int32_t	mac;		/* ie. CRYPTO_MD5_HMAC */
 
-	u_int32_t	keylen;		/* cipher key */
-	caddr_t		key;
-	int		mackeylen;	/* mac key */
-	caddr_t		mackey;
-
-  	u_int32_t	ses;		/* returns: session # */ 
+struct session_op {
+	__u16		algo_size;
+	__u16		key_size;	/* cipher key length */
+	__u16		hmackey_size;	/* mac key length */
+	__u16		icv_size;	/* authsize (ccm, gcm) */
+	__u8		data[0];
 };
 
 struct session2_op {
@@ -199,25 +199,24 @@
 	int		mackeylen;	/* mac key */
 	caddr_t		mackey;
 
-  	u_int32_t	ses;		/* returns: session # */ 
+	u_int32_t	ses;		/* returns: session # */
 	int		crid;		/* driver id + flags (rw) */
 	int		pad[4];		/* for future expansion */
 };
 
 struct crypt_op {
-	u_int32_t	ses;
-	u_int16_t	op;		/* i.e. COP_ENCRYPT */
 #define COP_NONE	0
 #define COP_ENCRYPT	1
 #define COP_DECRYPT	2
-	u_int16_t	flags;
-#define	COP_F_BATCH	0x0008		/* Batch op if possible */
-	u_int		len;
-	caddr_t		src, dst;	/* become iov[] inside kernel */
-	caddr_t		mac;		/* must be big enough for chosen MAC */
-	caddr_t		iv;
+	__u16		op;		/* i.e. COP_ENCRYPT */
+	__u16		flags;
+	__u16		iv_size;
+	__u16 		assoc_size;
+	__u32		src_size;
+	caddr_t		src_data;
+	caddr_t		dst_data;
+	__u8		data[0];	/* must be big enough for chosen MAC */
 };
-
 /*
  * Parameters for looking up a crypto driver/device by
  * device name or by id.  The latter are returned for
diff -Naur /user/openssl/openssl-0.9.8g/crypto/engine/eng_cryptodev.c /user/linux/openssl-0.9.8g/crypto/engine/eng_cryptodev.c
--- /user/openssl/openssl-0.9.8g/crypto/engine/eng_cryptodev.c 2008-08-07 18:05:02.916655000 -0700
+++ /user/linux/openssl-0.9.8g/crypto/engine/eng_cryptodev.c 2008-08-07 18:05:05.479325000 -0700
@@ -31,6 +31,9 @@
 #include <openssl/evp.h>
 #include <openssl/bn.h>
 
+#define CRYPTODEV_LINUX
+#define USE_CRYPTODEV_DIGESTS
+
 #if (defined(__unix__) || defined(unix)) && !defined(USG) && \
 	(defined(OpenBSD) || defined(__FreeBSD_version))
 #include <sys/param.h>
@@ -136,6 +139,43 @@
 	{ 0, NULL, NULL, 0 }
 };
 
+/*******************************************************************************
+* Table Lookup for Algorithms name(Crypto/hash name)
+* Helper Structure
+*******************************************************************************
+*/
+char *algo_map_tbl[CRYPTO_ALGORITHM_MAX] = {
+	[CRYPTO_DES_CBC]  	= "cbc(des)",
+	[CRYPTO_3DES_CBC] 	= "cbc(des3_ede)",
+	[CRYPTO_MD5_HMAC] 	= "hmac(md5)",
+	[CRYPTO_BLF_CBC]  	= "cbc(blowfish)",
+	[CRYPTO_CAST_CBC]	= "cbc(cast5)",
+	[CRYPTO_SKIPJACK_CBC]	= "camellia",
+	[CRYPTO_MD5_HMAC]	= "hmac(md5)",
+	[CRYPTO_SHA1_HMAC]	= "hmac(sha1)",
+	[CRYPTO_RIPEMD160_HMAC]	= "hmac(rmd160)",
+	[CRYPTO_MD5_KPDK]	= "",
+	[CRYPTO_SHA1_KPDK]	= "",
+	[CRYPTO_RIJNDAEL128_CBC] = "cbc(aes)",
+	[CRYPTO_AES_CBC]	= "cbc(aes)",
+	[CRYPTO_ARC4]		= "ecb(arc4)",
+	[CRYPTO_MD5]		= "md5",
+	[CRYPTO_SHA1]		= "sha1",
+	[CRYPTO_NULL_HMAC]	= "",
+	[CRYPTO_NULL_CBC]	= "",
+	[CRYPTO_DEFLATE_COMP]	= "deflate",
+	[CRYPTO_SHA2_256_HMAC]	= "hmac(sha256)",
+	[CRYPTO_SHA2_384_HMAC]	= "hmac(sha384)",
+	[CRYPTO_SHA2_512_HMAC]	= "hmac(sha512)",
+	[CRYPTO_CAMELLIA_CBC]	= "cbc(camellia)",
+	[CRYPTO_SHA2_256]	= "sha256",
+	[CRYPTO_SHA2_384]	= "sha384",
+	[CRYPTO_SHA2_512]	= "sha512",
+	[CRYPTO_RIPEMD160]	= "rmd160",
+	[CRYPTO_AES_GCM]	= "gcm(aes)",
+	[CRYPTO_AES_CCM]	= "ccm(aes)",
+};
+
 static struct {
 	int	id;
 	int	nid;
@@ -161,8 +201,8 @@
 	{ CRYPTO_RIPEMD160_HMAC,	NID_ripemd160,		16/*?*/},
 	{ CRYPTO_MD5_KPDK,		NID_undef,		0},
 	{ CRYPTO_SHA1_KPDK,		NID_undef,		0},
-	{ CRYPTO_MD5,			NID_md5,		16},
-	{ CRYPTO_SHA1,			NID_sha1,		20},
+	{ CRYPTO_MD5,			NID_md5,		0},
+	{ CRYPTO_SHA1,			NID_sha1,		0},
 	{ 0,				NID_undef,		0},
 };
 
@@ -170,6 +210,18 @@
  * Return a fd if /dev/crypto seems usable, 0 otherwise.
  */
 static int
+open_cryptodev_fd(void)
+{
+	int fd;
+	fd = open("/dev/crypto", O_RDWR, 0);
+	if (fd < 0) {
+		perror("open(/dev/crypto)");
+		return -1;
+	}
+	return fd;
+
+}
+static int
 open_dev_crypto(void)
 {
 	static int fd = -1;
@@ -279,27 +331,31 @@
 get_cryptodev_ciphers(const int **cnids)
 {
 	static int nids[CRYPTO_ALGORITHM_MAX];
-	struct session_op sess;
+	char datam[100];
+	struct session_op *op = (struct session_op *)datam;
 	int fd, i, count = 0;
-
-	if ((fd = get_dev_crypto()) < 0) {
-		*cnids = NULL;
-		return (0);
-	}
-	memset(&sess, 0, sizeof(sess));
-	sess.key = (caddr_t)"123456789abcdefghijklmno";
-
+	char *key;
+	
 	for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
 		if (ciphers[i].nid == NID_undef)
 			continue;
-		sess.cipher = ciphers[i].id;
-		sess.keylen = ciphers[i].keylen;
-		sess.mac = 0;
-		if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
-		    ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
+		if ((fd = open_cryptodev_fd()) < 0) {
+			*cnids = NULL;
+			return (0);
+		}
+		memset(op, 0, sizeof(struct session_op));
+		key = (caddr_t)"123456789abcdefghijklmno";
+		op->algo_size = strlen(algo_map_tbl[ciphers[i].id]);
+		op->key_size = ciphers[i].keylen;
+		op->hmackey_size = 0;
+		memcpy(op->data, algo_map_tbl[ciphers[i].id], op->algo_size);
+		op->data[op->algo_size++] = '\0';
+		memcpy(op->data + op->algo_size, key, op->key_size);
+		
+		if (ioctl(fd, CIOCGSESSION, op) != -1)
 			nids[count++] = ciphers[i].nid;
+		close(fd);
 	}
-	close(fd);
 
 	if (count > 0)
 		*cnids = nids;
@@ -318,26 +374,34 @@
 get_cryptodev_digests(const int **cnids)
 {
 	static int nids[CRYPTO_ALGORITHM_MAX];
-	struct session_op sess;
+	char data[100];
+	struct session_op *op = (struct session_op *)data;
 	int fd, i, count = 0;
+	char *mackey = NULL;
 
-	if ((fd = get_dev_crypto()) < 0) {
-		*cnids = NULL;
-		return (0);
-	}
-	memset(&sess, 0, sizeof(sess));
-	sess.mackey = (caddr_t)"123456789abcdefghijklmno";
 	for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) {
 		if (digests[i].nid == NID_undef)
 			continue;
-		sess.mac = digests[i].id;
-		sess.mackeylen = digests[i].keylen;
-		sess.cipher = 0;
-		if (ioctl(fd, CIOCGSESSION, &sess) != -1 &&
-		    ioctl(fd, CIOCFSESSION, &sess.ses) != -1)
+		if ((fd = open_cryptodev_fd()) < 0) {
+			*cnids = NULL;
+			return (0);
+		}
+
+		memset(op, 0, sizeof(struct session_op));
+		op->algo_size = strlen(algo_map_tbl[digests[i].id]);
+		op->key_size = 0;
+		op->hmackey_size = digests[i].keylen;
+		memcpy(op->data, algo_map_tbl[digests[i].id], op->algo_size);
+		if (op->hmackey_size)
+			mackey = (caddr_t)"123456789abcdefghijklmno";
+		op->data[op->algo_size++] = '\0';
+		memcpy(op->data + op->algo_size, mackey, op->hmackey_size);
+
+		if (ioctl(fd, CIOCGSESSION, op) != -1)
 			nids[count++] = digests[i].nid;
+		close(fd);
+		
 	}
-	close(fd);
 
 	if (count > 0)
 		*cnids = nids;
@@ -396,13 +460,17 @@
 #endif
 }
 
+
 static int
 cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 			const unsigned char *in, unsigned int inl)
 {
-	struct crypt_op cryp;
+
 	struct dev_crypto_state *state = ctx->cipher_data;
-	struct session_op *sess = &state->d_sess;
+	char dataop[100];
+	struct crypt_op *cryp = (struct crypt_op *)dataop;
+	int ret;
+	
 	void *iiv;
 	unsigned char save_iv[EVP_MAX_IV_LENGTH];
 
@@ -413,30 +481,30 @@
 	if ((inl % ctx->cipher->block_size) != 0)
 		return (0);
 
-	memset(&cryp, 0, sizeof(cryp));
+	memset(cryp, 0, sizeof(struct crypt_op));
 
-	cryp.ses = sess->ses;
-	cryp.flags = 0;
-	cryp.len = inl;
-	cryp.src = (caddr_t) in;
-	cryp.dst = (caddr_t) out;
-	cryp.mac = 0;
+	cryp->iv_size = ctx->cipher->iv_len;
+	cryp->assoc_size = 0;
+	cryp->src_size = inl;
+	cryp->src_data = (caddr_t) in;
+	cryp->dst_data = (caddr_t) out;
 
-	cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT;
+	cryp->op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT;
 
 	if (ctx->cipher->iv_len) {
-		cryp.iv = (caddr_t) ctx->iv;
+		memcpy(cryp->data, ctx->iv, cryp->iv_size);
 		if (!ctx->encrypt) {
 			iiv = (void *) in + inl - ctx->cipher->iv_len;
 			memcpy(save_iv, iiv, ctx->cipher->iv_len);
 		}
 	} else
-		cryp.iv = NULL;
-
-	if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) {
+	cryp->iv_size = 0;
+		
+	ret = ioctl(state->d_fd, CIOCCRYPT, cryp);
+	if (ret) {
 		/* XXX need better errror handling
-		 * this can fail for a number of different reasons.
-		 */
+		* this can fail for a number of different reasons.
+		*/
 		return (0);
 	}
 
@@ -448,44 +516,50 @@
 		memcpy(ctx->iv, iiv, ctx->cipher->iv_len);
 	}
 	return (1);
+
 }
 
 static int
 cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
 	const unsigned char *iv, int enc)
 {
+
 	struct dev_crypto_state *state = ctx->cipher_data;
-	struct session_op *sess = &state->d_sess;
+	char data[100];
+	struct session_op *op = (struct session_op *)data;
 	int cipher, i;
-
+	
 	for (i = 0; ciphers[i].id; i++)
 		if (ctx->cipher->nid == ciphers[i].nid &&
-		    ctx->cipher->iv_len <= ciphers[i].ivmax &&
-		    ctx->key_len == ciphers[i].keylen) {
+				  ctx->cipher->iv_len <= ciphers[i].ivmax &&
+				  ctx->key_len == ciphers[i].keylen) {
 			cipher = ciphers[i].id;
 			break;
-		}
+	  	}
 
 	if (!ciphers[i].id) {
-		state->d_fd = -1;
-		return (0);
+	 state->d_fd = -1;
+	 return (0);
 	}
+	
 
-	memset(sess, 0, sizeof(struct session_op));
-
-	if ((state->d_fd = get_dev_crypto()) < 0)
-		return (0);
-
-	sess->key = (unsigned char *)key;
-	sess->keylen = ctx->key_len;
-	sess->cipher = cipher;
+	if ((state->d_fd = open_cryptodev_fd()) < 0)
+	  return (0);
 
-	if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) {
-		close(state->d_fd);
-		state->d_fd = -1;
-		return (0);
+	memset(op, 0, sizeof(struct session_op));
+	op->algo_size = strlen(algo_map_tbl[cipher]);
+	op->key_size = ctx->key_len;
+	memcpy(op->data, algo_map_tbl[ciphers[i].id], op->algo_size);
+	op->data[op->algo_size++] = '\0';
+	memcpy(op->data + op->algo_size, (unsigned char *)key, op->key_size);
+
+	if (ioctl(state->d_fd, CIOCGSESSION, op) == -1) {
+			 close(state->d_fd);
+			  state->d_fd = -1;
+			return (0);
 	}
 	return (1);
+
 }
 
 /*
@@ -495,9 +569,9 @@
 static int
 cryptodev_cleanup(EVP_CIPHER_CTX *ctx)
 {
+
 	int ret = 0;
 	struct dev_crypto_state *state = ctx->cipher_data;
-	struct session_op *sess = &state->d_sess;
 
 	if (state->d_fd < 0)
 		return (0);
@@ -513,17 +587,14 @@
 	 * print messages to users of the library. hmm..
 	 */
 
-	if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) {
-		ret = 0;
-	} else {
-		ret = 1;
-	}
 	close(state->d_fd);
 	state->d_fd = -1;
 
 	return (ret);
+
 }
 
+
 /*
  * libcrypto EVP stuff - this is how we get wired to EVP so the engine
  * gets called when libcrypto requests a cipher NID.
@@ -678,8 +749,11 @@
 static int cryptodev_digest_init(EVP_MD_CTX *ctx)
 {
 	struct dev_crypto_state *state = ctx->md_data;
-	struct session_op *sess = &state->d_sess;
+	char data[100];
+	struct session_op *sess = (struct session_op *)data;
 	int digest;
+	int ret;
+	
 
 	if ((digest = digest_nid_to_cryptodev(ctx->digest->type)) == NID_undef){
 		printf("cryptodev_digest_init: Can't get digest \n");
@@ -688,16 +762,21 @@
 
 	memset(state, 0, sizeof(struct dev_crypto_state));
 
-	if ((state->d_fd = get_dev_crypto()) < 0) {
+	if ((state->d_fd = open_cryptodev_fd()) < 0) {
 		printf("cryptodev_digest_init: Can't get Dev \n");
 		return (0);
 	}
 
-	sess->mackey = state->dummy_mac_key;
-	sess->mackeylen = digest_key_length(ctx->digest->type);
-	sess->mac = digest;
-
-	if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) {
+	memset(sess, 0, sizeof(struct session_op));
+	sess->algo_size = strlen(algo_map_tbl[digest]);
+	sess->hmackey_size = digest_key_length(ctx->digest->type);
+	memcpy(sess->data, algo_map_tbl[digest], sess->algo_size);
+	sess->data[sess->algo_size++] = '\0';
+	if (sess->hmackey_size)
+		memcpy(sess->data + sess->algo_size,
+		       state->dummy_mac_key, sess->hmackey_size);
+	
+	if ((ret = ioctl(state->d_fd, CIOCGSESSION, sess)) < 0) {
 		close(state->d_fd);
 		state->d_fd = -1;
 		printf("cryptodev_digest_init: Open session failed\n");
@@ -710,9 +789,9 @@
 static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data,
 					size_t count)
 {
-	struct crypt_op cryp;
+	char datac[100];
+	struct crypt_op *cryp = (struct crypt_op *)datac;
 	struct dev_crypto_state *state = ctx->md_data;
-	struct session_op *sess = &state->d_sess;
 
 	if (!data || state->d_fd < 0) {
 		printf("cryptodev_digest_update: illegal inputs \n");
@@ -733,21 +812,19 @@
 		}
 
 		memcpy(state->mac_data + state->mac_len, data, count);
-   		state->mac_len += count;
+		state->mac_len += count;
 	
 		return (1);
 	}
 
-	memset(&cryp, 0, sizeof(cryp));
+	memset(cryp, 0, sizeof(struct crypt_op));
+	
+	cryp->src_size = count;
+	cryp->src_data = (caddr_t) data;
+	cryp->dst_data = state->digest_res;
 
-	cryp.ses = sess->ses;
-	cryp.flags = 0;
-	cryp.len = count;
-	cryp.src = (caddr_t) data;
-	cryp.dst = NULL;
-	cryp.mac = state->digest_res;
 
-	if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
+	if (ioctl(state->d_fd, CIOCCRYPT, cryp) < 0) {
 		printf("cryptodev_digest_update: digest failed \n");
 		return (0);
 	}
@@ -757,9 +834,9 @@
 
 static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
 {
-	struct crypt_op cryp;
+	char dataop[100];
+	struct crypt_op *cryp = (struct crypt_op *)dataop;
 	struct dev_crypto_state *state = ctx->md_data;
-	struct session_op *sess = &state->d_sess;
 
 	int ret = 1;
 
@@ -770,16 +847,13 @@
 
 	if (! (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) ) {
 		/* if application doesn't support one buffer */
-		memset(&cryp, 0, sizeof(cryp));
-
-		cryp.ses = sess->ses;
-		cryp.flags = 0;
-		cryp.len = state->mac_len;
-		cryp.src = state->mac_data;
-		cryp.dst = NULL;
-		cryp.mac = md;
+		memset(cryp, 0, sizeof(struct crypt_op));
+		
+		cryp->src_size = state->mac_len;
+		cryp->src_data = state->mac_data;
+		cryp->dst_data = md;
 
-		if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) {
+		if (ioctl(state->d_fd, CIOCCRYPT, cryp) < 0) {
 			printf("cryptodev_digest_final: digest failed Final\n");
 			return (0);
 		}
@@ -797,7 +871,6 @@
 {
 	int ret = 1;
 	struct dev_crypto_state *state = ctx->md_data;
-	struct session_op *sess = &state->d_sess;
 
 	if (state->d_fd < 0) {
 		printf("cryptodev_digest_cleanup: illegal input\n");
@@ -813,13 +886,7 @@
 	if (state->copy)
 		return 1;
 
-	if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) {
-		printf("cryptodev_digest_cleanup: failed to close session\n");
-		ret = 0;
-	} else {
-		ret = 1;
-	}
-	close(state->d_fd);	
+	close(state->d_fd);
 	state->d_fd = -1;
 
 	return (ret);
@@ -1334,6 +1401,8 @@
 
 	if (engine == NULL)
 		return;
+	/*Asymmetic Crypto Algorithms not yet supported by Linux Cryptodev*/
+#ifndef CRYPTODEV_LINUX
 	if ((fd = get_dev_crypto()) < 0) {
 		ENGINE_free(engine);
 		return;
@@ -1348,7 +1417,7 @@
 		return;
 	}
 	close(fd);
-
+#endif
 	if (!ENGINE_set_id(engine, "cryptodev") ||
 	    !ENGINE_set_name(engine, "BSD cryptodev engine") ||
 	    !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) ||

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: OpenSSL patch to support Linux CryptoAPI.
  2008-08-08 18:31 OpenSSL patch to support Linux CryptoAPI Shasi Pulijala
@ 2008-08-08 21:09 ` Evgeniy Polyakov
  2008-08-08 22:24   ` Loc Ho
  0 siblings, 1 reply; 6+ messages in thread
From: Evgeniy Polyakov @ 2008-08-08 21:09 UTC (permalink / raw)
  To: Shasi Pulijala; +Cc: linux-crypto, Loc Ho

Hi.

On Fri, Aug 08, 2008 at 11:31:58AM -0700, Shasi Pulijala (spulijala@amcc.com) wrote:
>  struct crypt_op {
> -	u_int32_t	ses;
> -	u_int16_t	op;		/* i.e. COP_ENCRYPT */
>  #define COP_NONE	0
>  #define COP_ENCRYPT	1
>  #define COP_DECRYPT	2
> -	u_int16_t	flags;
> -#define	COP_F_BATCH	0x0008		/* Batch op if possible */
> -	u_int		len;
> -	caddr_t		src, dst;	/* become iov[] inside kernel */
> -	caddr_t		mac;		/* must be big enough for chosen MAC */
> -	caddr_t		iv;
> +	__u16		op;		/* i.e. COP_ENCRYPT */
> +	__u16		flags;
> +	__u16		iv_size;
> +	__u16 		assoc_size;
> +	__u32		src_size;
> +	caddr_t		src_data;
> +	caddr_t		dst_data;
> +	__u8		data[0];	/* must be big enough for chosen MAC */
>  };

If above caddr_t is what I thought (i.e. a pointer or long type),
there is no way it can be correct. It is _NOT_ allowed to put
variable sized members into structures shared between kernel
and userspace.

-- 
	Evgeniy Polyakov

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: OpenSSL patch to support Linux CryptoAPI.
  2008-08-08 21:09 ` Evgeniy Polyakov
@ 2008-08-08 22:24   ` Loc Ho
  2008-08-09  6:29     ` Evgeniy Polyakov
  0 siblings, 1 reply; 6+ messages in thread
From: Loc Ho @ 2008-08-08 22:24 UTC (permalink / raw)
  To: Evgeniy Polyakov; +Cc: linux-crypto, Shasi Pulijala

Hi,

This sound like the only solution to passing more than one pointers from user space is via custom system call - such as (new) crypto_op(...). Am I correct?

-Loc

-----Original Message-----
From: linux-crypto-owner@vger.kernel.org [mailto:linux-crypto-owner@vger.kernel.org] On Behalf Of Evgeniy Polyakov
Sent: Friday, August 08, 2008 2:10 PM
To: Shasi Pulijala
Cc: linux-crypto@vger.kernel.org; Loc Ho
Subject: Re: OpenSSL patch to support Linux CryptoAPI.

Hi.

On Fri, Aug 08, 2008 at 11:31:58AM -0700, Shasi Pulijala (spulijala@amcc.com) wrote:
>  struct crypt_op {
> -	u_int32_t	ses;
> -	u_int16_t	op;		/* i.e. COP_ENCRYPT */
>  #define COP_NONE	0
>  #define COP_ENCRYPT	1
>  #define COP_DECRYPT	2
> -	u_int16_t	flags;
> -#define	COP_F_BATCH	0x0008		/* Batch op if possible */
> -	u_int		len;
> -	caddr_t		src, dst;	/* become iov[] inside kernel */
> -	caddr_t		mac;		/* must be big enough for chosen MAC */
> -	caddr_t		iv;
> +	__u16		op;		/* i.e. COP_ENCRYPT */
> +	__u16		flags;
> +	__u16		iv_size;
> +	__u16 		assoc_size;
> +	__u32		src_size;
> +	caddr_t		src_data;
> +	caddr_t		dst_data;
> +	__u8		data[0];	/* must be big enough for chosen MAC */
>  };

If above caddr_t is what I thought (i.e. a pointer or long type),
there is no way it can be correct. It is _NOT_ allowed to put
variable sized members into structures shared between kernel
and userspace.

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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: OpenSSL patch to support Linux CryptoAPI.
  2008-08-08 22:24   ` Loc Ho
@ 2008-08-09  6:29     ` Evgeniy Polyakov
  2008-08-11 18:53       ` Loc Ho
  0 siblings, 1 reply; 6+ messages in thread
From: Evgeniy Polyakov @ 2008-08-09  6:29 UTC (permalink / raw)
  To: Loc Ho; +Cc: linux-crypto, Shasi Pulijala

Hi.

On Fri, Aug 08, 2008 at 03:24:20PM -0700, Loc Ho (lho@amcc.com) wrote:
> This sound like the only solution to passing more than one pointers from user space is via custom system call - such as (new) crypto_op(...). Am I correct?

No, it is not a right solution. Linux has so ugly compat layer to fix
this problems, that it is much better not to look at it before the
dinner.

You do not need to pass multiple pointers, but instead a multiple data.
You can do that via single area provided to the kernel and multiple size
fields, where each one corresponds to the size of the contiguous sectors
in the provided data.

-- 
	Evgeniy Polyakov

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: OpenSSL patch to support Linux CryptoAPI.
  2008-08-09  6:29     ` Evgeniy Polyakov
@ 2008-08-11 18:53       ` Loc Ho
  2008-08-11 19:53         ` Evgeniy Polyakov
  0 siblings, 1 reply; 6+ messages in thread
From: Loc Ho @ 2008-08-11 18:53 UTC (permalink / raw)
  To: Evgeniy Polyakov; +Cc: linux-crypto, Shasi Pulijala

Hi,

>
>You do not need to pass multiple pointers, but instead a multiple data.
>You can do that via single area provided to the kernel and multiple size fields, where each 
> one corresponds to the size of the contiguous sectors in the provided data.

[Loc Ho]
It sounds like the solution is to format the data (parameter values, src, dst) into a single buffer. This will require memory copy of the source and destination data as follow:
1. User space formating the user space buffer that includes:
	1a) size parameter fields (this is required regardless)
	2b) parameter data such as IV, adata, and etc (this is required regardless)
	3c) copy the source data from application buffer into this single buffer (this is extra memcpy)
2. Kernel operation of the single user buffer (this is required regardless)
3. User space copy the destination data buffer into its appropriate memory pointer
	3a) For hash, it is just the hash
	3b) For crypto, it is the entire buffer (= to source length)
	3c) For aead, it is the entire buffer + aead ICV

As you can see, there is two extra memcpy's. There is noticeable performance on our SoC (AMCC 4xx) which memory copy is performed.

I was thinking. What do you think about passing multiple data pointer using writev (vector write)? And possible a similar idea for AIO.

-Loc



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: OpenSSL patch to support Linux CryptoAPI.
  2008-08-11 18:53       ` Loc Ho
@ 2008-08-11 19:53         ` Evgeniy Polyakov
  0 siblings, 0 replies; 6+ messages in thread
From: Evgeniy Polyakov @ 2008-08-11 19:53 UTC (permalink / raw)
  To: Loc Ho; +Cc: linux-crypto, Shasi Pulijala

Hi.

On Mon, Aug 11, 2008 at 11:53:41AM -0700, Loc Ho (lho@amcc.com) wrote:
> >You do not need to pass multiple pointers, but instead a multiple data.
> >You can do that via single area provided to the kernel and multiple size fields, where each 
> > one corresponds to the size of the contiguous sectors in the provided data.
> 
> [Loc Ho]
> It sounds like the solution is to format the data (parameter values, src, dst) into a single buffer. This will require memory copy of the source and destination data as follow:
> 1. User space formating the user space buffer that includes:
> 	1a) size parameter fields (this is required regardless)
> 	2b) parameter data such as IV, adata, and etc (this is required regardless)
> 	3c) copy the source data from application buffer into this single buffer (this is extra memcpy)
> 2. Kernel operation of the single user buffer (this is required regardless)
> 3. User space copy the destination data buffer into its appropriate memory pointer
> 	3a) For hash, it is just the hash
> 	3b) For crypto, it is the entire buffer (= to source length)
> 	3c) For aead, it is the entire buffer + aead ICV
> 
> As you can see, there is two extra memcpy's. There is noticeable performance on our SoC (AMCC 4xx) which memory copy is performed.

It will be buried in noise compared to crypto processing time, but you
still can try to optimize it.

> I was thinking. What do you think about passing multiple data pointer using writev (vector write)? And possible a similar idea for AIO.

Yes, that's a good approach.

Another one is to use a dedicated syscall.
It is up to you as developer decide, since all of them have advantages.

-- 
	Evgeniy Polyakov

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2008-08-11 19:53 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-08-08 18:31 OpenSSL patch to support Linux CryptoAPI Shasi Pulijala
2008-08-08 21:09 ` Evgeniy Polyakov
2008-08-08 22:24   ` Loc Ho
2008-08-09  6:29     ` Evgeniy Polyakov
2008-08-11 18:53       ` Loc Ho
2008-08-11 19:53         ` Evgeniy Polyakov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox