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 */
next 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.