/dev/crypto for Linux
PATCH 1/1 /dev/crypto for Linux
-----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 [email protected]
(+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-----
#
# Linux driver for /dev/crypto (aka CryptoDev)
# See http://www.logix.cz/michal/devel/cryptodev for details. #
# Signed-off-by: Michal Ludvig <[email protected]>
#
crypto/Kconfig +7 -0
@@ -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
crypto/Makefile +1 -0
@@ -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
crypto/cryptodev.c new file +563 -0
563 lines not on this page · raw message
include/linux/cryptodev.h new file +82 -0
82 lines not on this page · raw message
A message that is not in the archive (sent off-list or not yet received): [email protected]
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Michael Halcrow told me that:
Quoted 8 lines · Michal Ludvig
Quoted 4 lines
attached is a driver for OpenBSD-like
/dev/cryptodevice (aka CryptoDev) that makes a way for userspace processes to access ciphers provided by in-kernel CryptoAPI modules.Cool! Now if I'm interpreting this right, this is only good for working on up to one page worth of data at a time, right?
Of course the userspace can request encrypting any amount of data (well, multiple of blocksize), but only at most one page at a time is copied into the kernel, encrypted and returned back to the process' memory.
IMHO It is faster than allocating e.g. 4 MB in the kernel, copying all of this from userspace, encrypting and returning back. That wouldn't use the CPU cache too efficiently.
Quoted 3 lines
In cryptfs, I have written some functions that essentially do what your
FILL_SG()macro does, only it spreads across multiple sg's, if necessary. Do you think this might be appropriate for/dev/crypto?
As I'm currently working only on one kernel page at a time I think FILL_SG() is sufficient. But I'm definitely interested how to use multiple sg's at once (although I don't immediately ned it). Where can I see these functions? Maybe thay could go to some library directly in linux/crypto/...?
Michal Ludvig
- --
SUSE Labs [email protected]
(+420) 296.542.396 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
iD8DBQFBLEGhDDolCcRbIhgRApPrAJ9ghoyWXhxnk+wUQL9evde3o5uDqgCfdde8 OsMo/MlzKifupt1+pbNovYk=
=yKGK
-----END PGP SIGNATURE-----
Quoted 8 lines
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.
Let's see...
1) This increases context switches over a solution that links with libcrypto and libssl.
2) "build really lightweight programs with crypto support" implies that you think it's a benefit to use the kernel as your crypto lib. Shared libs
3) Your proposal actually avoids existing, working hardware crypto support such as Broadcom's hwcrypto driver which is fully supported by openssh.
4) "open it and use ioctls to transfer data" is typically a bad idea. ioctl(2) is a historical Unix mistake, to be avoided where possible. read(2)/write(2) are to be used to transfer data.
Jeff
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Jeff Garzik told me that:
Quoted 8 lines
Quoted 7 lines
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.
Quoted 4 lines
Let's see...
1) This increases context switches over a solution that links with libcrypto and libssl.
Indeed. It is not ment to replace libcrypto - just a possibility if needed.
Quoted 2 lines
2) "build really lightweight programs with crypto support" implies that you think it's a benefit to use the kernel as your crypto lib.
Yes, I think it may come handy in some scenarios. The algorithm is there in the kernel so why not use it from the userspace?
Also (a wild guess) similar interface could provide access to some key-management done in the kernel.
Quoted 3 lines
3) Your proposal actually avoids existing, working hardware crypto support such as Broadcom's hwcrypto driver which is fully supported by openssh.
Why avoids? I don't force OpenSSH to use it and I agree that typically the everything-in-the-userspace is better/faster. This is just an option for situations where no other cryptolib is available.
On my todo list is adding a module option for selecting allowed algorithms. Something like "allow=-ALL:+aes:+sha1".
Quoted 3 lines
4) "open it and use ioctls to transfer data" is typically a bad idea. ioctl(2) is a historical Unix mistake, to be avoided where possible. read(2)/write(2) are to be used to transfer data.
Well yes, my driver actually reuses the API from OpenBSD. I have no problem in changing (or extending) it but for now I did it this way for easier testing with the OpenSSL cryptodev engine. This can definitely evolve...
Michal Ludvig
- --
SUSE Labs [email protected]
(+420) 296.542.396 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
iD8DBQFBLKUoDDolCcRbIhgRApyzAKDYFtdhhDWgGeOtivbzPqsLbFT4ZACaA4H0 rdxbrN0z31pNtMomjMevbZU=
=6XVI
-----END PGP SIGNATURE-----
Quoted 1 line
+static int verbosity = 0;
no need to initialize to 0
crypto/cryptodev.c line 46
Quoted 4 lines
crypto/cryptodev.c new file +4
-0+module_param (verbosity, int,0644 ); +MODULE_PARM_DESC (verbosity,"0: normal, 1: verbose, 2: debug" ); + +#ifdef CRYPTODEV_STATS
whi is this not a config option?
Quoted 1 line
+static int
enable_stats= 0;
as above
crypto/cryptodev.c line 132
Quoted 1 line
crypto/cryptodev.c new file +1
-0+copy_from_user (alg_name, sop->alg_name, sop->alg_namelen);
this needs error checking.
crypto/cryptodev.c line 172
Quoted 1 line
crypto/cryptodev.c new file +1
-0+ keyp =kmalloc (sop->keylen,GFP_KERNEL );
retval checking
crypto/cryptodev.c line 173
Quoted 1 line
crypto/cryptodev.c new file +1
-0+copy_from_user (keyp, sop->key, sop->keylen);
error checking
crypto/cryptodev.c line 230
Quoted 5 lines
crypto/cryptodev.c new file +5
-0+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); + }
just use down please
Quoted 5 lines
crypto/cryptodev.c new file +5
-0+static int +clonefd (struct file *filp) +{ +struct files_struct * files = current->files; +int fd;
crypto/cryptodev.c line 461
Quoted 10 lines
crypto/cryptodev.c new file +10
-0+ + fd =get_unused_fd (); +if (fd >=0 ) { +get_file (filp); +FD_SET (fd, files->open_fds); +fd_install (fd, filp); + } + +return fd; +}
Yikes.
Quoted 8 lines
crypto/cryptodev.c new file +8
-0+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;
crypto/cryptodev.c line 480
Quoted 10 lines
crypto/cryptodev.c new file +10
-0+int ret, fd; + +if (!fcr) +BUG (); + +switch (cmd) { +case CRIOGET : + fd =clonefd (filp); +put_user (fd, (int *)arg); +return 0 ;
Extremly bad API. Just allow opening the device multiple times, and get a new context each time (can be stored in file->private_data
crypto/cryptodev.c line 487
Quoted 6 lines
crypto/cryptodev.c new file +6
-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));
missing error check.
crypto/cryptodev.c line 491
Quoted 4 lines
crypto/cryptodev.c new file +4
-0+return 0 ; + +case CIOCFSESSION : +get_user (ses, (uint32_t *)arg);
dito
crypto/cryptodev.c line 498
Quoted 7 lines
crypto/cryptodev.c new file +7
-0+ 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));
dito
besides the rather crappy implementation I'm not sure a crypto device makes any sense until we have hardware accelerators, and for these this is most likely not he right API
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Christoph Hellwig told me that:
Quoted 34 lines
Quoted 5 lines
crypto/cryptodev.c new file +5
-0+static int +clonefd (struct file *filp) +{ +struct files_struct * files = current->files; +int fd;crypto/cryptodev.c line 461
Quoted 10 lines
crypto/cryptodev.c new file +10
-0+ + fd =get_unused_fd (); +if (fd >=0 ) { +get_file (filp); +FD_SET (fd, files->open_fds); +fd_install (fd, filp); + } + +return fd; +}Yikes.
Quoted 14 lines
crypto/cryptodev.c new file +14
-0+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) {
Quoted 8 lines
crypto/cryptodev.c line 480
Quoted 4 lines
crypto/cryptodev.c new file +4
-0+case CRIOGET : + fd =clonefd (filp); +put_user (fd, (int *)arg); +return 0 ;Extremly bad API. Just allow opening the device multiple times, and get a new context each time (can be stored in
file->private_data
As I already said - these are relicts from the OpenBSD API. Will be redesigned and rewritten.
Michal Ludvig
- --
SUSE Labs [email protected]
(+420) 296.542.396 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
iD8DBQFBLLPQDDolCcRbIhgRAvglAJ48SiKsO2NymzGqsn9x8EYZSoMoMQCfWqsC t8E+AdtAgZc9Wi2Ta0xz1bs=
=emM8
-----END PGP SIGNATURE-----
Btw, please stop crossposting on lkml and moderated lists.
Quoted 6 lines · Michal Ludvig
How does it work?
- - Process opens/dev/cryptoand with a set ofioctl()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/cryptoand thus are automatically removed even if the process dies unexpectedly.
I don't think this is the way forward for the user crypto API. Rather than using the openbsd device as a starting point, we need to look at what is the best for Linux and work from there.
In any case, the openbsd device is the wrong model. An ioctl() based interface is just a set of backdoor syscalls, but with weak semantics, and a potential maintenance nightmare.
At this stage, the only real use for the device is to make it easier to test and benchmark the crypto modules, and I'm not sure if this is enough justification for integration with the kernel at this stage. Currently, the tcrypt module provides a convienient way to test modules on whatever architecture you can boot a kernel on, without the need for external userspace packages. It also tests some specific scatterlist cases. So, your crypto dev would not likely be considered a full replacement for tcrypt at this stage.
I would also want to see the user API evolve with the development of hardware crypto support, and not lock us into forever supporting some potentially inadequate/broken model. So, any user API at this stage should be marked experimental if it is going to be merged, if at all.
I think there are really two options for developing the user API:
1) a set of syscalls, or
2) a filesystem.
The main idea being to provide a well-structured, text-based (as far as possible) API with strong semantics. I have a preference for a filesystem API (and done some initial design), but have not established yet whether it is feasible compared to the syscall approach.
I would encourage you to look at a filesystem API, as a project which evolves with the addition of hardware support. I guess this is something we could discuss in more detail on the crypto list rather than annoy the lkml folk with.
- James
Signature · 2 lines
James Morris <[email protected]>
Quoted 11 lines · James Morris
Quoted 6 lines · Michal Ludvig
How does it work?
- - Process opens/dev/cryptoand with a set ofioctl()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/cryptoand thus are automatically removed even if the process dies unexpectedly.
Quoted 5 lines
I don't think this is the way forward for the user crypto API. Rather than using the openbsd device as a starting point, we need to look at what is the best for Linux and work from there.
In any case, the openbsd device is the wrong model. An
ioctl()based interface is just a set of backdoor syscalls, but with weak semantics, and a potential maintenance nightmare.At this stage, the only real use for the device is to make it easier to test and benchmark the crypto modules, and I'm not sure if this is enough justification for integration with the kernel at this stage. Currently, the tcrypt module provides a convienient way to test modules on whatever architecture you can boot a kernel on, without the need for external userspace packages. It also tests some specific scatterlist cases. So, your crypto dev would not likely be considered a full replacement for tcrypt at this stage.
The use of this would be to provide some access to crypto for portable programs which might be usefully run on systems which have not installed the big libs needed for usermode crypto. And it also addresses the reality that many people update their kernel more often than their libs, and new methods are more likely to be available there. For a low-volume task like encoding a key or other small chunk of data it might be that the overhead of the system call would be no more than the memory footprint of loading a lib to do a single operation.
And every time I see a new method in the kernel, I wonder why it's there is users can't access it?
Don't take this as a stand to include this, I'm just being devil's advocate and bringing up the benefits since multiple people are bringing up the drawbacks. If this was actually going to happen it *might* be done with a totally different interface and happen in a kernel thread or some such. One feature of MULTICS we don't have is the ability to execute kernel code in user mode, sort of like a shared library.
Signature · 3 lines
-bill davidsen ([email protected]) "The secret to procrastination is to put things off until the last possible moment - but no longer" -me