All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michal Ludvig <mludvig@suse.cz>
To: CryptoAPI List <cryptoapi@lists.logix.cz>
Cc: linux-kernel@vger.kernel.org, James Morris <jmorris@redhat.com>
Subject: [PATCH] /dev/crypto for Linux
Date: Tue, 24 Aug 2004 23:37:27 +0200	[thread overview]
Message-ID: <412BB517.4040204@suse.cz> (raw)

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

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi all,

attached is a driver for OpenBSD-like /dev/crypto device (aka CryptoDev)
that makes a way for userspace processes to access ciphers provided by
in-kernel CryptoAPI modules.

How does it work?
- - Process opens /dev/crypto and with a set of ioctl() commands does what
it wants to. I.e. obtains a crypto session, does the {enc,dec}ryption
and finally closes the session. The sessions are bound to "struct file"
of the open /dev/crypto and thus are automatically removed even if the
process dies unexpectedly.

What is it good for?
- - One can build really light-weigth programs with crypto support that
don't need any external libraries (e.g. OpenSSL) or built-in algorithms.
- - Easier testing of new CryptoAPI ciphers (later also hashes and maybe
asymmetric ciphers as well).
- - Once, maybe, userspace access to crypto accelerators through kernel
drivers.
- - etc :-)

For more info about /dev/crypto usage, demo programs and OpenSSL patch
see http://www.logix.cz/michal/devel/cryptodev/

Comments? Any chance to have this accepted into vanilla kernel?

Michal Ludvig
- --
SUSE Labs                    mludvig@suse.cz
(+420) 296.542.373        http://www.suse.cz
Personal homepage http://www.logix.cz/michal
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFBK7URDDolCcRbIhgRAhbSAJ4uf2jXY3X8zYcmbgqLATG7SuT0QwCg4IF6
RxZNkz+u+xjaI+pja8bSt3M=
=CrP/
-----END PGP SIGNATURE-----

[-- Attachment #2: cryptodev-2.6.8.diff --]
[-- Type: text/plain, Size: 17433 bytes --]

# 
# Linux driver for /dev/crypto (aka CryptoDev)
# See http://www.logix.cz/michal/devel/cryptodev for details.
# 
# Signed-off-by: Michal Ludvig <mludvig@suse.cz>
# 
Index: linux-2.6.8/crypto/Kconfig
===================================================================
--- linux-2.6.8.orig/crypto/Kconfig	2004-08-14 07:38:04.000000000 +0200
+++ linux-2.6.8/crypto/Kconfig	2004-08-24 22:58:21.000000000 +0200
@@ -9,6 +9,13 @@
 	help
 	  This option provides the core Cryptographic API.
 
+config CRYPTO_CRYPTODEV
+	tristate "Cryptodev (/dev/crypto) interface"
+	depends on CRYPTO
+	help
+	  Device /dev/crypto gives userspace programs access to 
+	  kernel crypto algorithms.
+
 config CRYPTO_HMAC
 	bool "HMAC support"
 	depends on CRYPTO
Index: linux-2.6.8/crypto/Makefile
===================================================================
--- linux-2.6.8.orig/crypto/Makefile	2004-08-14 07:38:04.000000000 +0200
+++ linux-2.6.8/crypto/Makefile	2004-08-24 22:58:21.000000000 +0200
@@ -7,6 +7,7 @@
 obj-$(CONFIG_CRYPTO) += api.o scatterwalk.o cipher.o digest.o compress.o \
 			$(proc-crypto-y)
 
+obj-$(CONFIG_CRYPTO_CRYPTODEV) += cryptodev.o
 obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
 obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o
 obj-$(CONFIG_CRYPTO_MD4) += md4.o
Index: linux-2.6.8/crypto/cryptodev.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.8/crypto/cryptodev.c	2004-08-24 23:27:09.784974592 +0200
@@ -0,0 +1,563 @@
+/*
+ * Driver for /dev/crypto device (aka CryptoDev)
+ *
+ * Copyright (c) 2004 Michal Ludvig <mludvig@suse.cz>, SuSE Labs
+ *
+ * Device /dev/crypto provides an interface for 
+ * accessing kernel CryptoAPI algorithms (ciphers,
+ * hashes) from userspace programs.
+ *
+ * /dev/crypto interface was originally introduced in
+ * OpenBSD and this module attempts to keep the API,
+ * although a bit extended.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/miscdevice.h>
+#include <linux/crypto.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <linux/random.h>
+#include <linux/cryptodev.h>
+#include <asm/uaccess.h>
+#include <asm/ioctl.h>
+#include <asm/scatterlist.h>
+
+MODULE_AUTHOR("Michal Ludvig <mludvig@suse.cz>");
+MODULE_DESCRIPTION("CryptoDev driver");
+MODULE_LICENSE("Dual BSD/GPL");
+
+/* ====== Compile-time config ====== */
+
+#define CRYPTODEV_STATS
+
+/* ====== Module parameters ====== */
+
+static int verbosity = 0;
+module_param(verbosity, int, 0644);
+MODULE_PARM_DESC(verbosity, "0: normal, 1: verbose, 2: debug");
+
+#ifdef CRYPTODEV_STATS
+static int enable_stats = 0;
+module_param(enable_stats, int, 0644);
+MODULE_PARM_DESC(enable_stats, "collect statictics about cryptodev usage");
+#endif
+
+/* ====== Debug helpers ====== */
+
+#define PFX "cryptodev: "
+#define dprintk(level,severity,format,a...)			\
+	do { 							\
+		if (level <= verbosity)				\
+			printk(severity PFX "%s[%u]: " format,	\
+			       current->comm, current->pid,	\
+			       ##a);				\
+	} while (0)
+
+/* ====== CryptoAPI ====== */
+
+#define FILL_SG(sg,ptr,len)					\
+	do {							\
+		(sg)->page = virt_to_page(ptr);			\
+		(sg)->offset = offset_in_page(ptr);		\
+		(sg)->length = len;				\
+		(sg)->dma_address = 0;				\
+	} while (0)
+
+static char *crypto_cipher_modes[] = {
+	[CRYPTO_TFM_MODE_ECB] = "ecb",
+	[CRYPTO_TFM_MODE_CBC] = "cbc",
+	[CRYPTO_TFM_MODE_CFB] = "cfb",
+	[CRYPTO_TFM_MODE_CTR] = "ctr",
+#if 0
+	[CRYPTO_TFM_MODE_OFB] = "ofb",
+#endif
+};
+
+struct csession {
+	struct list_head entry;
+	struct semaphore sem;
+	struct crypto_tfm *tfm;
+	uint32_t sid;
+#ifdef CRYPTODEV_STATS
+#if ! ((COP_ENCRYPT < 2) && (COP_DECRYPT < 2))
+#error Struct csession.stat uses COP_{ENCRYPT,DECRYPT} as indices. Do something!
+#endif
+	unsigned long long stat[2];
+	size_t stat_max_size, stat_count;
+#endif
+};
+
+struct fcrypt {
+	struct list_head list;
+	struct semaphore sem;
+};
+
+/* Prepare session for future use. */
+static int
+crypto_create_session(struct fcrypt *fcr, struct session_op *sop)
+{
+	struct csession	*ses_new, *ses_ptr;
+	struct crypto_tfm *tfm;
+	int mode, ret = 0;
+	char alg_name[MAX_ALG_NAME_LEN+1];
+	char *keyp;
+
+	/* Does the request make sense? */
+	if (!sop->cipher == !sop->mac) {
+		dprintk(1, KERN_DEBUG, "Both 'cipher' and 'mac' set or unset.\n");
+		return -EINVAL;
+	}
+
+	/* Copy-in the algorithm name if necessary. */
+	if (!sop->alg_namelen) {
+		/* Hmm, compatibility with OpenBSD CRYPTO_* constants...
+		   Should we support it? */
+		dprintk(2, KERN_DEBUG, "OpenBSD constants are not (yet?) supported.\n");
+		return -EINVAL;
+	}
+
+	if(sop->alg_namelen > MAX_ALG_NAME_LEN) {
+		dprintk(1, KERN_DEBUG, "Algorithm name too long (%zu > %u)\n",
+		       sop->alg_namelen, MAX_ALG_NAME_LEN);
+		return -EINVAL;
+	}
+
+	copy_from_user(alg_name, sop->alg_name, sop->alg_namelen);
+	alg_name[sop->alg_namelen] = '\0';
+
+	if(!sop->cipher) {
+		dprintk(2, KERN_DEBUG, "Hashes are not yet supported.\n");
+		return -EINVAL;
+	}
+	
+	switch (sop->cipher & CRYPTO_FLAG_MASK) {
+		case CRYPTO_FLAG_ECB:	mode = CRYPTO_TFM_MODE_ECB; break;
+		case CRYPTO_FLAG_CBC:	mode = CRYPTO_TFM_MODE_CBC; break;
+		case CRYPTO_FLAG_CFB:	mode = CRYPTO_TFM_MODE_CFB; break;
+		case CRYPTO_FLAG_CTR:	mode = CRYPTO_TFM_MODE_CTR; break;
+#if 0
+		/* These modes are not yet supported. */
+		case CRYPTO_FLAG_OFB:	mode = CRYPTO_TFM_MODE_OFB; break;
+#endif
+		default:		return -EINVAL;
+	}
+
+	/* Set-up crypto transform. */
+	tfm = crypto_alloc_tfm(alg_name, mode);
+	if (!tfm) {
+		dprintk(1, KERN_DEBUG, "Failed to load transform for %s %s\n",
+		       alg_name, crypto_cipher_modes[mode]);
+		return -EINVAL;
+	}
+
+	/* Was correct key length supplied? */
+	if ((sop->keylen < crypto_tfm_alg_min_keysize(tfm)) ||
+	    (sop->keylen > crypto_tfm_alg_max_keysize(tfm))) {
+		dprintk(1, KERN_DEBUG,
+			"Wrong keylen '%zu' for algorithm '%s'. Use %u to %u.\n",
+		       sop->keylen, alg_name, crypto_tfm_alg_min_keysize(tfm), 
+		       crypto_tfm_alg_max_keysize(tfm));
+		crypto_free_tfm(tfm);
+		return -EINVAL;
+	}
+
+	/* Copy the key from user and set to TFM. */
+	keyp = kmalloc(sop->keylen, GFP_KERNEL);
+	copy_from_user(keyp, sop->key, sop->keylen);
+	ret = crypto_cipher_setkey(tfm, keyp, sop->keylen);
+	kfree(keyp);
+	if (ret) {
+		dprintk(2, KERN_DEBUG,
+			"Setting key failed for %s-%zu-%s: flags=0x%X\n",
+			alg_name, sop->keylen*8, crypto_cipher_modes[mode],
+			tfm->crt_flags);
+		dprintk(2, KERN_DEBUG,
+			"(see CRYPTO_TFM_RES_* in <linux/crypto.h> for details)\n");
+		crypto_free_tfm(tfm);
+		return -EINVAL;
+	}
+
+	/* Create a session and put it to the list. */
+	ses_new = kmalloc(sizeof(*ses_new), GFP_KERNEL);
+	if(!ses_new)
+		return -ENOMEM;
+
+	memset(ses_new, 0, sizeof(*ses_new));
+	get_random_bytes(&ses_new->sid, sizeof(ses_new->sid));
+	ses_new->tfm = tfm;
+	init_MUTEX(&ses_new->sem);
+
+	down(&fcr->sem);
+restart:
+	list_for_each_entry(ses_ptr, &fcr->list, entry) {
+		/* Check for duplicate SID */
+		if (unlikely(ses_new->sid == ses_ptr->sid)) {
+			get_random_bytes(&ses_new->sid, sizeof(ses_new->sid));
+			/* Unless we have a broken RNG this 
+			   shouldn't loop forever... ;-) */
+			goto restart;
+		}
+	}
+
+	list_add(&ses_new->entry, &fcr->list);
+	up(&fcr->sem);
+
+	dprintk(2, KERN_DEBUG, "Added session 0x%08X (%s-%zu-%s)\n",
+		ses_new->sid, alg_name, sop->keylen*8, crypto_cipher_modes[mode]);
+	
+	/* Fill in some values for the user. */
+	sop->ses = ses_new->sid;
+	sop->blocksize = crypto_tfm_alg_blocksize(tfm);
+
+	return 0;
+}
+
+/* Everything that needs to be done when remowing a session. */
+static inline void
+crypto_destroy_session(struct csession *ses_ptr)
+{
+	if(down_trylock(&ses_ptr->sem)) {
+		dprintk(2, KERN_DEBUG, "Waiting for semaphore of sid=0x%08X\n",
+			ses_ptr->sid);
+		down(&ses_ptr->sem);
+	}
+	dprintk(2, KERN_DEBUG, "Removed session 0x%08X\n", ses_ptr->sid);
+#if defined(CRYPTODEV_STATS)
+	if(enable_stats)
+		dprintk(2, KERN_DEBUG,
+			"Usage in Bytes: enc=%llu, dec=%llu, max=%zu, avg=%lu, cnt=%zu\n",
+			ses_ptr->stat[COP_ENCRYPT], ses_ptr->stat[COP_DECRYPT],
+			ses_ptr->stat_max_size, ses_ptr->stat_count > 0
+				? ((unsigned long)(ses_ptr->stat[COP_ENCRYPT]+
+						   ses_ptr->stat[COP_DECRYPT]) / 
+				   ses_ptr->stat_count) : 0,
+			ses_ptr->stat_count);
+#endif
+	crypto_free_tfm(ses_ptr->tfm);
+	ses_ptr->tfm = NULL;
+	up(&ses_ptr->sem);
+	kfree(ses_ptr);
+}
+
+/* Look up a session by ID and remove. */
+static int
+crypto_finish_session(struct fcrypt *fcr, uint32_t sid)
+{
+	struct csession *tmp, *ses_ptr;
+	struct list_head *head;
+	int ret = 0;
+	
+	down(&fcr->sem);
+	head = &fcr->list;
+	list_for_each_entry_safe(ses_ptr, tmp, head, entry) {
+		if(ses_ptr->sid == sid) {
+			list_del(&ses_ptr->entry);
+			crypto_destroy_session(ses_ptr);
+			break;
+		}
+	}
+
+	if (!ses_ptr) {
+		dprintk(1, KERN_ERR, "Session with sid=0x%08X not found!\n", sid);
+		ret = -ENOENT;
+	}
+	up(&fcr->sem);
+
+	return ret;
+}
+
+/* Remove all sessions when closing the file */
+static int
+crypto_finish_all_sessions(struct fcrypt *fcr)
+{
+	struct csession *tmp, *ses_ptr;
+
+	down(&fcr->sem);
+	list_for_each_entry_safe(ses_ptr, tmp, &fcr->list, entry) {
+		list_del(&ses_ptr->entry);
+		crypto_destroy_session(ses_ptr);
+	}
+	up(&fcr->sem);
+
+	return 0;
+}
+
+/* Look up session by session ID. The returned session is locked. */
+static struct csession *
+crypto_get_session_by_sid(struct fcrypt *fcr, uint32_t sid)
+{
+	struct csession *ses_ptr;
+
+	down(&fcr->sem);
+	list_for_each_entry(ses_ptr, &fcr->list, entry) {
+		if(ses_ptr->sid == sid) {
+			down(&ses_ptr->sem);
+			break;
+		}
+	}
+	up(&fcr->sem);
+
+	return ses_ptr;
+}
+
+/* This is the main crypto function - feed it with plaintext 
+   and get a ciphertext (or vice versa :-) */
+static int
+crypto_run(struct fcrypt *fcr, struct crypt_op *cop)
+{
+	char *data, *ivp;
+	char __user *src, __user *dst;
+	struct scatterlist sg;
+	struct csession *ses_ptr;
+	unsigned int ivsize;
+	size_t nbytes, bufsize;
+	int ret = 0;
+
+	nbytes = cop->len;
+
+	if (cop->op != COP_ENCRYPT && cop->op != COP_DECRYPT) {
+		dprintk(1, KERN_DEBUG, "invalid operation op=%u\n", cop->op);
+		return -EINVAL;
+	}
+
+	ses_ptr = crypto_get_session_by_sid(fcr, cop->ses);
+	if (!ses_ptr) {
+		dprintk(1, KERN_ERR, "invalid session ID=0x%08X\n", cop->ses);
+		return -EINVAL;
+	}
+
+	if (nbytes % crypto_tfm_alg_blocksize(ses_ptr->tfm)) {
+		dprintk(1, KERN_ERR,
+			"data size (%zu) isn't a multiple of block size (%u)\n",
+			nbytes, crypto_tfm_alg_blocksize(ses_ptr->tfm));
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+	bufsize = PAGE_SIZE < nbytes ? PAGE_SIZE : nbytes;
+	data = (char*)__get_free_page(GFP_KERNEL);
+
+	if (unlikely(!data)) {
+		ret = -ENOMEM;
+		goto out_unlock;
+	}
+
+	ivsize = crypto_tfm_alg_ivsize(ses_ptr->tfm);
+
+	ivp = kmalloc(ivsize, GFP_KERNEL);
+	if (unlikely(!ivp)) {
+		free_page((unsigned long)data);
+		ret = -ENOMEM;
+		goto out_unlock;
+	}
+
+	if (cop->iv) {
+		copy_from_user(ivp, cop->iv, ivsize);
+		crypto_cipher_set_iv(ses_ptr->tfm, ivp, ivsize);
+	}
+
+	src = cop->src;
+	dst = cop->dst;
+
+	while(nbytes > 0) {
+		size_t current_len = nbytes > bufsize ? bufsize : nbytes;
+
+		copy_from_user(data, src, current_len);
+
+		FILL_SG(&sg, data, current_len);
+
+		if (cop->op == COP_DECRYPT)
+			ret = crypto_cipher_decrypt(ses_ptr->tfm, &sg, &sg, current_len);
+		else
+			ret = crypto_cipher_encrypt(ses_ptr->tfm, &sg, &sg, current_len);
+
+		if (unlikely(ret)) {
+			dprintk(0, KERN_ERR, "CryptoAPI failure: flags=0x%x\n",
+				ses_ptr->tfm->crt_flags);
+			goto out;
+		}
+
+		copy_to_user(dst, data, current_len);
+
+		nbytes -= current_len;
+		src += current_len;
+		dst += current_len;
+	}
+
+#if defined(CRYPTODEV_STATS)
+	if (enable_stats) {
+		/* this is safe - we check cop->op at the function entry */
+		ses_ptr->stat[cop->op] += cop->len;
+		if (ses_ptr->stat_max_size < cop->len)
+			ses_ptr->stat_max_size = cop->len;
+		ses_ptr->stat_count++;
+	}
+#endif
+
+out:
+	free_page((unsigned long)data);
+
+	kfree(ivp);
+
+out_unlock:
+	up(&ses_ptr->sem);
+
+	return ret;
+}
+
+/* ====== /dev/crypto ====== */
+
+static int
+cryptodev_open(struct inode *inode, struct file *filp)
+{
+	struct fcrypt *fcr;
+
+	fcr = kmalloc(sizeof(*fcr), GFP_KERNEL);
+	if(!fcr)
+		return -ENOMEM;
+
+	memset(fcr, 0, sizeof(*fcr));
+	init_MUTEX(&fcr->sem);
+	INIT_LIST_HEAD(&fcr->list);
+	filp->private_data = fcr;
+
+	return 0;
+}
+
+static int
+cryptodev_release(struct inode *inode, struct file *filp)
+{
+	struct fcrypt *fcr = filp->private_data;
+
+	if(fcr) {
+		crypto_finish_all_sessions(fcr);
+		kfree(fcr);
+		filp->private_data = NULL;
+	}
+	return 0;
+}
+
+static int
+clonefd(struct file *filp)
+{
+	struct files_struct * files = current->files;
+	int fd;
+
+	fd = get_unused_fd();
+	if (fd >= 0) {
+		get_file(filp);
+		FD_SET(fd, files->open_fds);
+		fd_install(fd, filp);
+	}
+
+	return fd;
+}
+
+static int
+cryptodev_ioctl(struct inode *inode, struct file *filp,
+		unsigned int cmd, unsigned long arg)
+{
+	struct session_op sop;
+	struct crypt_op cop;
+	struct fcrypt *fcr = filp->private_data;
+	uint32_t ses;
+	int ret, fd;
+
+	if (!fcr)
+		BUG();
+
+	switch (cmd) {
+		case CRIOGET:
+			fd = clonefd(filp);
+			put_user(fd, (int*)arg);
+			return 0;
+			
+		case CIOCGSESSION:
+			copy_from_user(&sop, (void*)arg, sizeof(sop));
+			ret = crypto_create_session(fcr, &sop);
+			if (ret)
+				return ret;
+			copy_to_user((void*)arg, &sop, sizeof(sop));
+			return 0;
+
+		case CIOCFSESSION:
+			get_user(ses, (uint32_t*)arg);
+			ret = crypto_finish_session(fcr, ses);
+			return ret;
+
+		case CIOCCRYPT:
+			copy_from_user(&cop, (void*)arg, sizeof(cop));
+			ret = crypto_run(fcr, &cop);
+			copy_to_user((void*)arg, &cop, sizeof(cop));
+			return ret;
+
+		default:
+			return -EINVAL;
+	}
+}
+
+struct file_operations cryptodev_fops = {
+	.owner = THIS_MODULE,
+	.open = cryptodev_open,
+	.release = cryptodev_release,
+	.ioctl = cryptodev_ioctl,
+};
+
+struct miscdevice cryptodev = {
+	.minor = CRYPTODEV_MINOR,
+	.name = "crypto",
+	.fops = &cryptodev_fops,
+};
+
+static int
+cryptodev_register(void)
+{
+	int rc;
+
+	rc = misc_register (&cryptodev);
+	if (rc) {
+		printk(KERN_ERR PFX "registeration of /dev/crypto failed\n");
+		return rc;
+	}
+
+	return 0;
+}
+
+static void
+cryptodev_deregister(void)
+{
+	misc_deregister(&cryptodev);
+}
+
+/* ====== Module init/exit ====== */
+
+int __init
+init_cryptodev(void)
+{
+	int rc;
+	
+	rc = cryptodev_register();
+	if (rc)
+		return rc;
+
+	printk(KERN_INFO PFX "driver loaded.\n");
+
+	return 0;
+}
+
+void __exit
+exit_cryptodev(void)
+{
+	cryptodev_deregister();
+	printk(KERN_INFO PFX "driver unloaded.\n");
+}
+
+module_init(init_cryptodev);
+module_exit(exit_cryptodev);
Index: linux-2.6.8/include/linux/cryptodev.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.8/include/linux/cryptodev.h	2004-08-24 23:33:09.460295632 +0200
@@ -0,0 +1,82 @@
+/*
+ * Driver for /dev/crypto device (aka CryptoDev)
+ *
+ * Copyright (c) 2004 Michal Ludvig <mludvig@suse.cz>, SuSE Labs
+ *
+ * Structures and ioctl command names were taken from
+ * OpenBSD to preserve compatibility with their API.
+ *
+ */
+
+#ifndef _CRYPTODEV_H
+#define _CRYPTODEV_H
+
+#ifndef __KERNEL__
+#include <inttypes.h>
+#endif
+
+#define	CRYPTODEV_MINOR	MISC_DYNAMIC_MINOR
+
+#define CRYPTO_FLAG_ECB		0x0000
+#define CRYPTO_FLAG_CBC		0x0001
+#define CRYPTO_FLAG_CFB		0x0002
+#define CRYPTO_FLAG_OFB		0x0003
+#define CRYPTO_FLAG_CTR		0x0004
+#define CRYPTO_FLAG_HMAC	0x0010
+#define CRYPTO_FLAG_MASK	0x00FF
+
+#define	CRYPTO_CIPHER_NAME	0x0100
+#define	CRYPTO_CIPHER_NAME_CBC	(CRYPTO_CIPHER_NAME | CRYPTO_FLAG_CBC)
+#define	CRYPTO_HASH_NAME	0x0200
+#define	CRYPTO_HASH_NAME_HMAC	(CRYPTO_HASH_NAME | CRYPTO_FLAG_HMAC)
+
+/* ioctl parameter to create a session */
+struct session_op {
+	unsigned int	cipher;		/* e.g. CRYPTO_DES_CBC */
+	unsigned int	mac;		/* e.g. CRYPTO_MD5_HMAC */
+	char		*alg_name;	/* set cipher=CRYPTO_CIPHER_NAME
+					   or  mac=CRYPTO_HASH_NAME */
+	#define	MAX_ALG_NAME_LEN 128
+	size_t		alg_namelen;
+
+	size_t		keylen;		/* cipher key */
+	char		*key;
+	int		mackeylen;	/* mac key */
+	char		*mackey;
+
+	/* Return values */
+	unsigned int	blocksize;	/* selected algorithm's block size */
+	uint32_t	ses;		/* session ID */
+};
+
+/* ioctl parameter to request a crypt/decrypt operation against a session  */
+struct crypt_op {
+	uint32_t	ses;		/* from session_op->ses */
+	#define COP_DECRYPT	0
+	#define COP_ENCRYPT	1
+	uint32_t	op;		/* ie. COP_ENCRYPT */
+	uint32_t	flags;		/* unused */
+
+	size_t		len;
+	char		*src, *dst;
+	char		*mac;
+	char		*iv;
+};
+
+/* clone original filedescriptor */
+#define CRIOGET         _IOWR('c', 100, uint32_t)
+
+/* create crypto session */
+#define CIOCGSESSION    _IOWR('c', 101, struct session_op)
+
+/* finish crypto session */
+#define CIOCFSESSION    _IOW('c', 102, uint32_t)
+
+/* request encryption/decryptions of a given buffer */
+#define CIOCCRYPT       _IOWR('c', 103, struct crypt_op)
+
+/* ioctl()s for asym-crypto. Not yet supported. */
+#define CIOCKEY         _IOWR('c', 104, void *)
+#define CIOCASYMFEAT    _IOR('c', 105, uint32_t)
+
+#endif /* _CRYPTODEV_H */

             reply	other threads:[~2004-08-24 21:51 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-08-24 21:37 Michal Ludvig [this message]
     [not found] ` <20040824215351.GA9272@halcrow.us>
2004-08-25  7:37   ` [PATCH] /dev/crypto for Linux Michal Ludvig
2004-08-25 14:17     ` Jeff Garzik
2004-08-25 14:41       ` Michal Ludvig
2004-08-25 14:26 ` Christoph Hellwig
2004-08-25 15:44   ` Michal Ludvig
2004-08-25 14:42 ` Christoph Hellwig
2004-08-25 14:44 ` James Morris
2004-08-25 21:28   ` Bill Davidsen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=412BB517.4040204@suse.cz \
    --to=mludvig@suse.cz \
    --cc=cryptoapi@lists.logix.cz \
    --cc=jmorris@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.