netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* RFC: Crypto API User-interface
@ 2010-09-07  8:42 Herbert Xu
  2010-09-07  9:18 ` Tomas Mraz
                   ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Herbert Xu @ 2010-09-07  8:42 UTC (permalink / raw)
  To: Linux Crypto Mailing List, netdev

Hi:

This is what I am proposing for the Crypto API user-interface.

Note that this is the interface for operations.  There will be
a separate interface (most likely netlink) for configuring crypto
algorithms, e.g., picking a specific AES implementation as the
system default.

First of all let's have a quick look at what the user-space side
looks like for AEAD:

	int op;

	/* This fd corresponds to a tfm object. */
	tfmfd = socket(AF_ALG, SOCK_STREAM, 0);

	alg.type = "aead";
	alg.name = "ccm(aes)";
	bind(tfmfd, &alg, sizeof(alg));

	setsockopt(tfmfd, SOL_ALG, ALG_AEAD_SET_KEY, key, keylen);

The idea here is that each tfm corresponds to a listening socket.

	/* Each listen call generates one or more fds for input/output
	 * that behave like pipes.
	 */
	listen(tfmfd, 0);
	/* fd for encryption/decryption */
	opfd = accept(tfmfd, NULL, 0);
	/* fd for associated data */
	adfd = accept(tfmfd, NULL, 0);

Each session corresponds to one or more connections obtained from
that socket.  The number depends on the number of inputs/outputs
of that particular type of operation.  For most types, there will
be a s ingle connection/file descriptor that is used for both input
and output.  AEAD is one of the few that require two inputs.

	/* These may also be set through sendmsg(2) cmsgs. */
	op = ALG_AEAD_OP_ENCRYPT;
	setsockopt(opfd, SOL_ALG, ALG_AEAD_OP, op, sizeof(op));
	setsockopt(opfd, SOL_ALG, ALG_AEAD_SET_IV, iv, ivlen);

	/* Like pipes, larges writes will block!
	 * For AEAD, ensure the socket buffer is large enough.
	 * For ciphers, whenever the write blocks start reading.
	 * For hashes, writes should never block.
	 */
	write(opfd, plain, datalen);
	write(adfd, ad, adlen);

	/* The first read triggers the operation. */
	read(opfd, crypt, datalen);

	op = ALG_AEAD_OP_DECRYPT;
	setsockopt(opfd, SOL_ALG, ALG_AEAD_OP, op, sizeof(op));

	write(opfd, crypt, datalen);
	write(adfd, ad, adlen);

	/* Returns -1 with errno EBADMSG if auth fails */
	read(defd, plain, datalen);

	/* Zero-copy */
	splice(cryptfd, NULL, opfd, NULL, datalen, SPLICE_F_MOVE|SPLIFE_F_MORE);
	/* We allow writes to be split into multiple system calls. */
	splice(cryptfd2, NULL, opfd, NULL, datalen, SPLICE_F_MOVE);
	splice(adatafd, NULL, adfd, NULL, adlen, SPLICE_F_MOVE);

	/* For now reading is copy-only, if and when vmsplice
	 * starts supporting zero-copy to user then we can do it
	 * as well.
	 */
	read(opfd, plain, datalen);

Ciphers/compression are pretty much the same sans adfd.

For hashes:

	/* This fd corresponds to a tfm object. */
	tfmfd = socket(AF_ALG, SOCK_STREAM, 0);

	alg.type = "hash";
	alg.name = "xcbc(aes)";
	bind(tfmfd, &alg, sizeof(alg));

	setsockopt(tfmfd, SOL_ALG, ALG_HASH_SET_KEY, key, keylen);

	/* Each listen call generates one or more fds for input/output
	 * that behave like pipes.
	 */
	listen(tfmfd, 0);
	/* fd for hashing */
	opfd = accept(tfmfd, NULL, 0);

	/* MSG_MORE prevents finalisation */
	send(opfd, plain, datalen, MSG_MORE);

	/* Reads partial hash state */
	read(opfd, state, statelen);

	/* Restore from a partial hash state */
	send(opfd, state, statelen, MSG_OOB);

	/* Finalise */
	send(opfd, plain, 0, 0);
	read(opfd, hash, hashlen);

Please comment.

Thanks,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

* Re: RFC: Crypto API User-interface
  2010-09-07  8:42 Herbert Xu
@ 2010-09-07  9:18 ` Tomas Mraz
  2010-09-07 14:06 ` Christoph Hellwig
  2010-10-19 13:44 ` Herbert Xu
  2 siblings, 0 replies; 20+ messages in thread
From: Tomas Mraz @ 2010-09-07  9:18 UTC (permalink / raw)
  To: Herbert Xu; +Cc: Linux Crypto Mailing List, netdev

On Tue, 2010-09-07 at 16:42 +0800, Herbert Xu wrote: 
> Hi:
> 
> This is what I am proposing for the Crypto API user-interface.
> 
> Note that this is the interface for operations.  There will be
> a separate interface (most likely netlink) for configuring crypto
> algorithms, e.g., picking a specific AES implementation as the
> system default.
> 
> First of all let's have a quick look at what the user-space side
> looks like for AEAD:
> 
> 	int op;
> 
> 	/* This fd corresponds to a tfm object. */
> 	tfmfd = socket(AF_ALG, SOCK_STREAM, 0);
> 
> 	alg.type = "aead";
> 	alg.name = "ccm(aes)";
> 	bind(tfmfd, &alg, sizeof(alg));
> 
> 	setsockopt(tfmfd, SOL_ALG, ALG_AEAD_SET_KEY, key, keylen);
> 
> The idea here is that each tfm corresponds to a listening socket.
> 
> 	/* Each listen call generates one or more fds for input/output
> 	 * that behave like pipes.
> 	 */
> 	listen(tfmfd, 0);
> 	/* fd for encryption/decryption */
> 	opfd = accept(tfmfd, NULL, 0);
> 	/* fd for associated data */
> 	adfd = accept(tfmfd, NULL, 0);

This has much much higher overhead in terms of number of needed syscalls
than the previously proposed ioctl interface. Of course in case of large
data operation the overhead converges to just one or two (for AEAD) more
syscalls (1. ioctl vs. 2. write+read). But there will be many real
use-cases where all the setup of the fds will be done again and again.
And of course it adds an overhead in terms of number of file descriptors
needed for each crypto operation. Where the old interface had just
constant one fd overhead per lifetime of the process, this interface has
3 fds per crypto context in use.

> Each session corresponds to one or more connections obtained from
> that socket.  The number depends on the number of inputs/outputs
> of that particular type of operation.  For most types, there will
> be a s ingle connection/file descriptor that is used for both input
> and output.  AEAD is one of the few that require two inputs.
> 
> 	/* These may also be set through sendmsg(2) cmsgs. */
> 	op = ALG_AEAD_OP_ENCRYPT;
> 	setsockopt(opfd, SOL_ALG, ALG_AEAD_OP, op, sizeof(op));
> 	setsockopt(opfd, SOL_ALG, ALG_AEAD_SET_IV, iv, ivlen);
> 
> 	/* Like pipes, larges writes will block!
> 	 * For AEAD, ensure the socket buffer is large enough.
> 	 * For ciphers, whenever the write blocks start reading.
> 	 * For hashes, writes should never block.
> 	 */
> 	write(opfd, plain, datalen);
> 	write(adfd, ad, adlen);
> 
> 	/* The first read triggers the operation. */
> 	read(opfd, crypt, datalen);
> 
> 	op = ALG_AEAD_OP_DECRYPT;
> 	setsockopt(opfd, SOL_ALG, ALG_AEAD_OP, op, sizeof(op));
> 
> 	write(opfd, crypt, datalen);
> 	write(adfd, ad, adlen);
> 
> 	/* Returns -1 with errno EBADMSG if auth fails */
> 	read(defd, plain, datalen);
> 
> 	/* Zero-copy */
> 	splice(cryptfd, NULL, opfd, NULL, datalen, SPLICE_F_MOVE|SPLIFE_F_MORE);
> 	/* We allow writes to be split into multiple system calls. */
> 	splice(cryptfd2, NULL, opfd, NULL, datalen, SPLICE_F_MOVE);
> 	splice(adatafd, NULL, adfd, NULL, adlen, SPLICE_F_MOVE);
> 
> 	/* For now reading is copy-only, if and when vmsplice
> 	 * starts supporting zero-copy to user then we can do it
> 	 * as well.
This is also serious performance penalty for now.

> 	read(opfd, plain, datalen);
> 
> Ciphers/compression are pretty much the same sans adfd.
> 
> For hashes:
> 
> 	/* This fd corresponds to a tfm object. */
> 	tfmfd = socket(AF_ALG, SOCK_STREAM, 0);
> 
> 	alg.type = "hash";
> 	alg.name = "xcbc(aes)";
> 	bind(tfmfd, &alg, sizeof(alg));
> 
> 	setsockopt(tfmfd, SOL_ALG, ALG_HASH_SET_KEY, key, keylen);
> 
> 	/* Each listen call generates one or more fds for input/output
> 	 * that behave like pipes.
> 	 */
> 	listen(tfmfd, 0);
> 	/* fd for hashing */
> 	opfd = accept(tfmfd, NULL, 0);
> 
> 	/* MSG_MORE prevents finalisation */
> 	send(opfd, plain, datalen, MSG_MORE);
> 
> 	/* Reads partial hash state */
> 	read(opfd, state, statelen);
> 
> 	/* Restore from a partial hash state */
> 	send(opfd, state, statelen, MSG_OOB);
> 
> 	/* Finalise */
> 	send(opfd, plain, 0, 0);
> 	read(opfd, hash, hashlen);
Note, that one of frequent hash operations is duplicating the internal
hash state. How this would be done with this API?

-- 
Tomas Mraz
No matter how far down the wrong road you've gone, turn back.
                                              Turkish proverb

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

* Re: RFC: Crypto API User-interface
       [not found] <1590523029.1055831283858598965.JavaMail.root@zmail07.collab.prod.int.phx2.redhat.com>
@ 2010-09-07 11:27 ` Miloslav Trmac
  2010-09-07 14:07   ` Herbert Xu
  0 siblings, 1 reply; 20+ messages in thread
From: Miloslav Trmac @ 2010-09-07 11:27 UTC (permalink / raw)
  To: Herbert Xu; +Cc: Linux Crypto Mailing List, netdev

Hello,
----- "Herbert Xu" <herbert@gondor.hengli.com.au> wrote:
> First of all let's have a quick look at what the user-space side
> looks like for AEAD:
> 
> 	/* Each listen call generates one or more fds for input/output
> 	 * that behave like pipes.
> 	 */
> 	listen(tfmfd, 0);
> 	/* fd for encryption/decryption */
> 	opfd = accept(tfmfd, NULL, 0);
> 	/* fd for associated data */
> 	adfd = accept(tfmfd, NULL, 0);
If nothing else, two consecutive accept() calls with different semantics go rather strongly against the spirit of the socket API IMHO.

> 	/* These may also be set through sendmsg(2) cmsgs. */
> 	op = ALG_AEAD_OP_ENCRYPT;
> 	setsockopt(opfd, SOL_ALG, ALG_AEAD_OP, op, sizeof(op));
> 	setsockopt(opfd, SOL_ALG, ALG_AEAD_SET_IV, iv, ivlen);
So that is 8 syscalls to initialize a single AEAD operation.
 
> 	/* Like pipes, larges writes will block!
> 	 * For AEAD, ensure the socket buffer is large enough.
> 	 * For ciphers, whenever the write blocks start reading.
> 	 * For hashes, writes should never block.
> 	 */
How does one know the buffer is large enough?

"Whenever the write blocks start reading" turns a trivial loop submitting one buffer-size at a time into something that would be much easier to get wrong.


> 	/* Zero-copy */
> 	splice(cryptfd, NULL, opfd, NULL, datalen,
> SPLICE_F_MOVE|SPLIFE_F_MORE);
So that is "zero copy on input if your data come from a file descriptor"?  I'm not sure many applications will be able to take advantage of that, and there's still the output copy.

Also, is SPLICE_F_MOVE actually implemented?

Why use splice() at all?  Simple write() gives the driver the __user pointers that can be used to access the underlying pages directly.  Yanking user-space pages out from the process address space to make them "owned" by the crypto driver, causing more page faults when the process wants to reuse the buffer, does not seem like a performance improvement.

> Please comment.
I can't really see any advantage in trying to use existing syscalls for crypto when the syscalls were clearly not intended for the purpose.  setsockopt() is fine for sockets because options are set up once per connection, and the connection very rarely lasts less than several milliseconds; crypto operation options have to be configured much more often.

7 syscalls to compute a single hash is very difficult to accept.
     Mirek

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

* Re: RFC: Crypto API User-interface
  2010-09-07  8:42 Herbert Xu
  2010-09-07  9:18 ` Tomas Mraz
@ 2010-09-07 14:06 ` Christoph Hellwig
  2010-09-07 14:11   ` Herbert Xu
  2010-09-07 14:57   ` Nikos Mavrogiannopoulos
  2010-10-19 13:44 ` Herbert Xu
  2 siblings, 2 replies; 20+ messages in thread
From: Christoph Hellwig @ 2010-09-07 14:06 UTC (permalink / raw)
  To: Herbert Xu; +Cc: Linux Crypto Mailing List, netdev, linux-kernel

On Tue, Sep 07, 2010 at 04:42:13PM +0800, Herbert Xu wrote:
> Hi:
> 
> This is what I am proposing for the Crypto API user-interface.

Can you explain why we would ever want a userspace interface to it?

doing crypto in kernel for userspace consumers sis simply insane.
It's computational intensive code which has no business in kernel space
unless absolutely required (e.g. for kernel consumers).  In addition
to that adding the context switch overhead and address space transitions
is god awfull too.

This all very much sounds like someone had far too much crack.

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

* Re: RFC: Crypto API User-interface
  2010-09-07 11:27 ` Miloslav Trmac
@ 2010-09-07 14:07   ` Herbert Xu
  0 siblings, 0 replies; 20+ messages in thread
From: Herbert Xu @ 2010-09-07 14:07 UTC (permalink / raw)
  To: Miloslav Trmac; +Cc: Linux Crypto Mailing List, netdev

On Tue, Sep 07, 2010 at 07:27:47AM -0400, Miloslav Trmac wrote:
> Hello,
> ----- "Herbert Xu" <herbert@gondor.hengli.com.au> wrote:
> > First of all let's have a quick look at what the user-space side
> > looks like for AEAD:
> > 
> > 	/* Each listen call generates one or more fds for input/output
> > 	 * that behave like pipes.
> > 	 */
> > 	listen(tfmfd, 0);
> > 	/* fd for encryption/decryption */
> > 	opfd = accept(tfmfd, NULL, 0);
> > 	/* fd for associated data */
> > 	adfd = accept(tfmfd, NULL, 0);
> If nothing else, two consecutive accept() calls with different semantics go rather strongly against the spirit of the socket API IMHO.

If you have a better suggestion of obtaining multiple fds for
multiple input streams please let us know.

> > 	/* These may also be set through sendmsg(2) cmsgs. */
> > 	op = ALG_AEAD_OP_ENCRYPT;
> > 	setsockopt(opfd, SOL_ALG, ALG_AEAD_OP, op, sizeof(op));
> > 	setsockopt(opfd, SOL_ALG, ALG_AEAD_SET_IV, iv, ivlen);
> So that is 8 syscalls to initialize a single AEAD operation.

If this interface is fast enough for TCP, it ought to be fast
enough for crypto.

> > 	/* Like pipes, larges writes will block!
> > 	 * For AEAD, ensure the socket buffer is large enough.
> > 	 * For ciphers, whenever the write blocks start reading.
> > 	 * For hashes, writes should never block.
> > 	 */
> How does one know the buffer is large enough?

For anything other than AEAD you don't have to know.  As I said
it behaves just like a pipe.  If you know how to use a pipe you'll
know how to deal with this.

For AEAD we need this as otherwise you can chew up an unlimited
amount of kernel memory.

> "Whenever the write blocks start reading" turns a trivial loop submitting one buffer-size at a time into something that would be much easier to get wrong.

We don't have a choice.  We cannot allow user-space to use up
an unlimted amount of kernel memory.  At some point you've got
to say stop.

Now the usual socket limits should be good enough for most users.
That is, if you're encrypting anything less than 128K you shouldn't
care.

If you need more just do a setsockopt (subject to limits set by
the admin of course).

> > 	/* Zero-copy */
> > 	splice(cryptfd, NULL, opfd, NULL, datalen,
> > SPLICE_F_MOVE|SPLIFE_F_MORE);
> So that is "zero copy on input if your data come from a file descriptor"?  I'm not sure many applications will be able to take advantage of that, and there's still the output copy.
> 
> Also, is SPLICE_F_MOVE actually implemented?

Actually it doesn't matter, it'll do zero-copy by default.

> Why use splice() at all?  Simple write() gives the driver the __user pointers that can be used to access the underlying pages directly.  Yanking user-space pages out from the process address space to make them "owned" by the crypto driver, causing more page faults when the process wants to reuse the buffer, does not seem like a performance improvement.

For someone working on security I thought you would've considered
the pitfalls of inventing yet another interface for moving data
between the kernel/user-space.

Also you're wrong about the page faults, splicing does not cause
additional page faults at all.  This is the whole point of the
vmsplice(2) interface, we don't play with page tables.

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

* Re: RFC: Crypto API User-interface
  2010-09-07 14:06 ` Christoph Hellwig
@ 2010-09-07 14:11   ` Herbert Xu
  2010-09-07 14:24     ` Christoph Hellwig
  2010-09-07 14:49     ` Nikos Mavrogiannopoulos
  2010-09-07 14:57   ` Nikos Mavrogiannopoulos
  1 sibling, 2 replies; 20+ messages in thread
From: Herbert Xu @ 2010-09-07 14:11 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Linux Crypto Mailing List, netdev, linux-kernel

On Tue, Sep 07, 2010 at 10:06:46AM -0400, Christoph Hellwig wrote:
> On Tue, Sep 07, 2010 at 04:42:13PM +0800, Herbert Xu wrote:
> > Hi:
> > 
> > This is what I am proposing for the Crypto API user-interface.
> 
> Can you explain why we would ever want a userspace interface to it?
> 
> doing crypto in kernel for userspace consumers sis simply insane.
> It's computational intensive code which has no business in kernel space
> unless absolutely required (e.g. for kernel consumers).  In addition
> to that adding the context switch overhead and address space transitions
> is god awfull too.
> 
> This all very much sounds like someone had far too much crack.

FWIW I don't care about user-space using kernel software crypto at
all.  It's the security people that do.

The purpose of the user-space API is to export the hardware crypto
devices to user-space.  This means PCI devices mostly, as things
like aesni-intel can already be used without kernel help.

Now as a side-effect if this means that we can shut the security
people up about adding another interface then all the better.  But
I will certainly not go out of the way to add more crap to the
kernel for that purpose.

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

* Re: RFC: Crypto API User-interface
  2010-09-07 14:11   ` Herbert Xu
@ 2010-09-07 14:24     ` Christoph Hellwig
  2010-09-07 14:39       ` Herbert Xu
  2010-09-07 14:49     ` Nikos Mavrogiannopoulos
  1 sibling, 1 reply; 20+ messages in thread
From: Christoph Hellwig @ 2010-09-07 14:24 UTC (permalink / raw)
  To: Herbert Xu
  Cc: Christoph Hellwig, Linux Crypto Mailing List, netdev,
	linux-kernel

On Tue, Sep 07, 2010 at 10:11:12PM +0800, Herbert Xu wrote:
> FWIW I don't care about user-space using kernel software crypto at
> all.  It's the security people that do.

And since when did we care about their crack pipe dreams?

> The purpose of the user-space API is to export the hardware crypto
> devices to user-space.  This means PCI devices mostly, as things
> like aesni-intel can already be used without kernel help.

I don't think they matter in practice.  We have less than a handfull
of drivers for them, and with CPUs gaining proper instructions they
are even less useful.  In addition any sane PCI card should just
allow userspace mapping of their descriptors.

> Now as a side-effect if this means that we can shut the security
> people up about adding another interface then all the better.  But
> I will certainly not go out of the way to add more crap to the
> kernel for that purpose.

So what is the real use case for this?  In addition to kernel bloat
the real fear I have is that the security wankers will just configure
the userspace crypto libraries to always use the kernel interface
just in case, and once that happens we will have to deal with the whole
mess.  Especially for RHEL and Fedora where the inmantes now run the
asylum in that respect.

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

* Re: RFC: Crypto API User-interface
       [not found] <1847066281.1081601283869883727.JavaMail.root@zmail07.collab.prod.int.phx2.redhat.com>
@ 2010-09-07 14:34 ` Miloslav Trmac
  2010-09-07 14:41   ` Herbert Xu
  2010-09-07 14:51   ` Christoph Hellwig
  0 siblings, 2 replies; 20+ messages in thread
From: Miloslav Trmac @ 2010-09-07 14:34 UTC (permalink / raw)
  To: Herbert Xu; +Cc: Linux Crypto Mailing List, netdev

----- "Herbert Xu" <herbert@gondor.hengli.com.au> wrote:
> On Tue, Sep 07, 2010 at 07:27:47AM -0400, Miloslav Trmac wrote:
> > Hello,
> > ----- "Herbert Xu" <herbert@gondor.hengli.com.au> wrote:
> > > First of all let's have a quick look at what the user-space side
> > > looks like for AEAD:
> > > 
> > > 	/* Each listen call generates one or more fds for input/output
> > > 	 * that behave like pipes.
> > > 	 */
> > > 	listen(tfmfd, 0);
> > > 	/* fd for encryption/decryption */
> > > 	opfd = accept(tfmfd, NULL, 0);
> > > 	/* fd for associated data */
> > > 	adfd = accept(tfmfd, NULL, 0);
> > If nothing else, two consecutive accept() calls with different
> semantics go rather strongly against the spirit of the socket API
> IMHO.
> 
> If you have a better suggestion of obtaining multiple fds for
> multiple input streams please let us know.
- Don't use a FD for associated data that is limited to 16? bytes

- Don't use file descriptors for input data at all, if it makes the interface so complex.

> > > 	/* These may also be set through sendmsg(2) cmsgs. */
> > > 	op = ALG_AEAD_OP_ENCRYPT;
> > > 	setsockopt(opfd, SOL_ALG, ALG_AEAD_OP, op, sizeof(op));
> > > 	setsockopt(opfd, SOL_ALG, ALG_AEAD_SET_IV, iv, ivlen);
> > So that is 8 syscalls to initialize a single AEAD operation.
> 
> If this interface is fast enough for TCP, it ought to be fast
> enough for crypto.
Crypto has much smaller granularity than TCP.  A single TLS handshake involves something on the order of 20 separate crypto operations in addition to setting up the four transforms used throughout the life of the session.

A single SHA-256 password verification is more than 5000 hash operations by default.

> > Why use splice() at all?  Simple write() gives the driver the __user
> pointers that can be used to access the underlying pages directly. 
> Yanking user-space pages out from the process address space to make
> them "owned" by the crypto driver, causing more page faults when the
> process wants to reuse the buffer, does not seem like a performance
> improvement.
> 
> For someone working on security I thought you would've considered
> the pitfalls of inventing yet another interface for moving data
> between the kernel/user-space.
The data will in the usual case be in user-space memory, not in file descriptors.  Existing low-level crypto libraries have no access to the file descriptors that are used to work with the data.  And even in the case of TLS where the data does come through a file descriptor, a MAC is then computed on it - so at most half of the (steady-state) crypto is coming through a file descriptor.

Finally, when the application uses file descriptors, it uses them to transfer the _encrypted_ form of the data; it keeps plaintext in memory in order to use it.  So avoiding the trip to userspace protects primarily the kind of data that does not need protecting.
    Mirek

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

* Re: RFC: Crypto API User-interface
  2010-09-07 14:24     ` Christoph Hellwig
@ 2010-09-07 14:39       ` Herbert Xu
  0 siblings, 0 replies; 20+ messages in thread
From: Herbert Xu @ 2010-09-07 14:39 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Linux Crypto Mailing List, netdev, linux-kernel

On Tue, Sep 07, 2010 at 10:24:27AM -0400, Christoph Hellwig wrote:
> 
> I don't think they matter in practice.  We have less than a handfull
> of drivers for them, and with CPUs gaining proper instructions they
> are even less useful.  In addition any sane PCI card should just
> allow userspace mapping of their descriptors.

I totally agree that mainstream CPUs won't need this at all.

However we still have embedded users where the CPUs may not be
powerful enough per se or where they want to use their CPUs for
other work.

There are also cases such as the Niagra SPU which may not be
easy to manage from user-space (correct me if I'm wrong Dave).

> > Now as a side-effect if this means that we can shut the security
> > people up about adding another interface then all the better.  But
> > I will certainly not go out of the way to add more crap to the
> > kernel for that purpose.
> 
> So what is the real use case for this?  In addition to kernel bloat
> the real fear I have is that the security wankers will just configure
> the userspace crypto libraries to always use the kernel interface
> just in case, and once that happens we will have to deal with the whole
> mess.  Especially for RHEL and Fedora where the inmantes now run the
> asylum in that respect.

I will let the security people answer this :)

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

* Re: RFC: Crypto API User-interface
  2010-09-07 14:34 ` Miloslav Trmac
@ 2010-09-07 14:41   ` Herbert Xu
  2010-09-07 14:51   ` Christoph Hellwig
  1 sibling, 0 replies; 20+ messages in thread
From: Herbert Xu @ 2010-09-07 14:41 UTC (permalink / raw)
  To: Miloslav Trmac; +Cc: Linux Crypto Mailing List, netdev

On Tue, Sep 07, 2010 at 10:34:25AM -0400, Miloslav Trmac wrote:
>
> > > > 	/* These may also be set through sendmsg(2) cmsgs. */
> > > > 	op = ALG_AEAD_OP_ENCRYPT;
> > > > 	setsockopt(opfd, SOL_ALG, ALG_AEAD_OP, op, sizeof(op));
> > > > 	setsockopt(opfd, SOL_ALG, ALG_AEAD_SET_IV, iv, ivlen);
> > > So that is 8 syscalls to initialize a single AEAD operation.
> > 
> > If this interface is fast enough for TCP, it ought to be fast
> > enough for crypto.
> Crypto has much smaller granularity than TCP.  A single TLS handshake involves something on the order of 20 separate crypto operations in addition to setting up the four transforms used throughout the life of the session.
> 
> A single SHA-256 password verification is more than 5000 hash operations by default.

You're clearly one of those crazy security people.

If you're processing a small amount of data the last thing you want
is to go through the kernel if you care about performance.

Now on the other hand if you had to go through the kernel for
certification reasons then why are you talking about performance?

> The data will in the usual case be in user-space memory, not in file descriptors.  Existing low-level crypto libraries have no access to the file descriptors that are used to work with the data.  And even in the case of TLS where the data does come through a file descriptor, a MAC is then computed on it - so at most half of the (steady-state) crypto is coming through a file descriptor.

man vmsplice

Also learn to wrap your lines please.

Thanks,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

* Re: RFC: Crypto API User-interface
  2010-09-07 14:11   ` Herbert Xu
  2010-09-07 14:24     ` Christoph Hellwig
@ 2010-09-07 14:49     ` Nikos Mavrogiannopoulos
  1 sibling, 0 replies; 20+ messages in thread
From: Nikos Mavrogiannopoulos @ 2010-09-07 14:49 UTC (permalink / raw)
  To: Herbert Xu
  Cc: Christoph Hellwig, Linux Crypto Mailing List, netdev,
	linux-kernel

On Tue, Sep 7, 2010 at 4:11 PM, Herbert Xu <herbert@gondor.hengli.com.au> wrote:

>> > This is what I am proposing for the Crypto API user-interface.
>>
>> Can you explain why we would ever want a userspace interface to it?
>>
>> doing crypto in kernel for userspace consumers sis simply insane.
>> It's computational intensive code which has no business in kernel space
>> unless absolutely required (e.g. for kernel consumers).  In addition
>> to that adding the context switch overhead and address space transitions
>> is god awfull too.
>>
>> This all very much sounds like someone had far too much crack.
>
> FWIW I don't care about user-space using kernel software crypto at
> all.  It's the security people that do.

Then I'd suggest to not enforce your design over to people who have
thought and have interests on that. The NCR api which you rejected
(for not supporting kernel keyring - which your design also doesn't!),
has specific security goals and protects against specific threats.
This design here has been proposed by you quite many times in the past
and neither you, nor anyone else bothered implementing it. Now we have
two working implementations that offer user-space access to crypto
operations, (the openbsd cryptodev port), and NCR, but you discard
them and insist on a different design. Maybe yours is better (you have
to argue about that)... Probably I'd use it if it was there, but it
isn't.

regards,
Nikos

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

* Re: RFC: Crypto API User-interface
  2010-09-07 14:34 ` Miloslav Trmac
  2010-09-07 14:41   ` Herbert Xu
@ 2010-09-07 14:51   ` Christoph Hellwig
  2010-09-07 14:54     ` Miloslav Trmac
  1 sibling, 1 reply; 20+ messages in thread
From: Christoph Hellwig @ 2010-09-07 14:51 UTC (permalink / raw)
  To: Miloslav Trmac; +Cc: Herbert Xu, Linux Crypto Mailing List, netdev

On Tue, Sep 07, 2010 at 10:34:25AM -0400, Miloslav Trmac wrote:
> - Don't use a FD for associated data that is limited to 16? bytes
> 
> - Don't use file descriptors for input data at all, if it makes the interface so complex.

Calling into the kernel for 16 bytes of crypto is a braindead idea to
start with.  To preve3nt idiots like you from abusing it we should
simply limit any userlevel crypto API to:

 a) hardware crypto that is not directly user space accesible
 b) page size or larger data

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

* Re: RFC: Crypto API User-interface
       [not found] <834983542.1086561283871074929.JavaMail.root@zmail07.collab.prod.int.phx2.redhat.com>
@ 2010-09-07 14:52 ` Miloslav Trmac
  2010-09-07 14:55   ` Christoph Hellwig
  0 siblings, 1 reply; 20+ messages in thread
From: Miloslav Trmac @ 2010-09-07 14:52 UTC (permalink / raw)
  To: Herbert Xu; +Cc: Linux Crypto Mailing List, netdev

----- "Herbert Xu" <herbert@gondor.hengli.com.au> wrote:
> On Tue, Sep 07, 2010 at 10:34:25AM -0400, Miloslav Trmac wrote:
> >
> > > > > 	/* These may also be set through sendmsg(2) cmsgs. */
> > > > > 	op = ALG_AEAD_OP_ENCRYPT;
> > > > > 	setsockopt(opfd, SOL_ALG, ALG_AEAD_OP, op, sizeof(op));
> > > > > 	setsockopt(opfd, SOL_ALG, ALG_AEAD_SET_IV, iv, ivlen);
> > > > So that is 8 syscalls to initialize a single AEAD operation.
> > > 
> > > If this interface is fast enough for TCP, it ought to be fast
> > > enough for crypto.
> > Crypto has much smaller granularity than TCP.  A single TLS
> handshake involves something on the order of 20 separate crypto
> operations in addition to setting up the four transforms used
> throughout the life of the session.
> > 
> > A single SHA-256 password verification is more than 5000 hash
> operations by default.
> 
> If you're processing a small amount of data the last thing you want
> is to go through the kernel if you care about performance.
> 
> Now on the other hand if you had to go through the kernel for
> certification reasons then why are you talking about performance?

Because in the real world people want both certification, features _and_ performance.  If all they cared about is certification they could just as well buy a pencil.
     Mirek

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

* Re: RFC: Crypto API User-interface
  2010-09-07 14:51   ` Christoph Hellwig
@ 2010-09-07 14:54     ` Miloslav Trmac
  0 siblings, 0 replies; 20+ messages in thread
From: Miloslav Trmac @ 2010-09-07 14:54 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Herbert Xu, Linux Crypto Mailing List, netdev


----- "Christoph Hellwig" <hch@infradead.org> wrote:

> On Tue, Sep 07, 2010 at 10:34:25AM -0400, Miloslav Trmac wrote:
> > - Don't use a FD for associated data that is limited to 16? bytes
> > 
> > - Don't use file descriptors for input data at all, if it makes the
> interface so complex.
> 
> Calling into the kernel for 16 bytes of crypto is a braindead idea to
> start with.  To preve3nt idiots like you
1) It was Herbert who used AEAD as an example
2) That's how AEAD works: One large input stream, one very small.
     Mirek

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

* Re: RFC: Crypto API User-interface
  2010-09-07 14:52 ` RFC: Crypto API User-interface Miloslav Trmac
@ 2010-09-07 14:55   ` Christoph Hellwig
  0 siblings, 0 replies; 20+ messages in thread
From: Christoph Hellwig @ 2010-09-07 14:55 UTC (permalink / raw)
  To: Miloslav Trmac; +Cc: Herbert Xu, Linux Crypto Mailing List, netdev

On Tue, Sep 07, 2010 at 10:52:03AM -0400, Miloslav Trmac wrote:
> Because in the real world people want both certification, features _and_ performance.  If all they cared about is certification they could just as well buy a pencil.

Okay Mr Smartass.  Please put away your crackpipe and get down to earth.
There is absolutely no good reason to ever do crypto for userspace
applications in the kernel.  If any certification requires that it's not
worth the paper it's written on.  In fact there's more enough criticial
systems that do not even have separate kernel vs userspace boundaries.

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

* Re: RFC: Crypto API User-interface
  2010-09-07 14:06 ` Christoph Hellwig
  2010-09-07 14:11   ` Herbert Xu
@ 2010-09-07 14:57   ` Nikos Mavrogiannopoulos
  2010-09-07 14:59     ` Christoph Hellwig
  1 sibling, 1 reply; 20+ messages in thread
From: Nikos Mavrogiannopoulos @ 2010-09-07 14:57 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Herbert Xu, Linux Crypto Mailing List, netdev, linux-kernel

On Tue, Sep 7, 2010 at 4:06 PM, Christoph Hellwig <hch@infradead.org> wrote:
>> This is what I am proposing for the Crypto API user-interface.
>
> Can you explain why we would ever want a userspace interface to it?
>
> doing crypto in kernel for userspace consumers sis simply insane.
> It's computational intensive code which has no business in kernel space
> unless absolutely required (e.g. for kernel consumers).  In addition
> to that adding the context switch overhead and address space transitions
> is god awfull too.
> This all very much sounds like someone had far too much crack.

Or that someone is not really aware of some cryptographic uses.
Embedded systems have crypto accelerators in hardware available
through kernel device drivers. In the systems I worked the
accelerators via a crypto device interface gave a 50x to 100x boost in
crypto operations and relieved the CPU from doing them.

regards,
Nikos

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

* Re: RFC: Crypto API User-interface
  2010-09-07 14:57   ` Nikos Mavrogiannopoulos
@ 2010-09-07 14:59     ` Christoph Hellwig
  0 siblings, 0 replies; 20+ messages in thread
From: Christoph Hellwig @ 2010-09-07 14:59 UTC (permalink / raw)
  To: Nikos Mavrogiannopoulos
  Cc: Christoph Hellwig, Herbert Xu, Linux Crypto Mailing List, netdev,
	linux-kernel

On Tue, Sep 07, 2010 at 04:57:04PM +0200, Nikos Mavrogiannopoulos wrote:
> Or that someone is not really aware of some cryptographic uses.
> Embedded systems have crypto accelerators in hardware available
> through kernel device drivers. In the systems I worked the
> accelerators via a crypto device interface gave a 50x to 100x boost in
> crypto operations and relieved the CPU from doing them.

An interface to external crypto co-process _can_ be useful.  It
certainly isn't for the tiny requests where mr crackhead complains about
the overhead.   So if we do want to design an interface for addons cards
we need to expose a threshold from which it makes sense to use it, and
not even bother using for the simply software in-kernel algorithms.

Which is something that could be done easily using a variant of
Herbert's interface.

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

* Re: RFC: Crypto API User-interface
  2010-09-07  8:42 Herbert Xu
  2010-09-07  9:18 ` Tomas Mraz
  2010-09-07 14:06 ` Christoph Hellwig
@ 2010-10-19 13:44 ` Herbert Xu
  2010-10-20 10:24   ` Nikos Mavrogiannopoulos
  2010-11-04 17:34   ` Herbert Xu
  2 siblings, 2 replies; 20+ messages in thread
From: Herbert Xu @ 2010-10-19 13:44 UTC (permalink / raw)
  To: Linux Crypto Mailing List, netdev, Linux Kernel Mailing List

On Tue, Sep 07, 2010 at 04:42:13PM +0800, Herbert Xu wrote:
> 
> This is what I am proposing for the Crypto API user-interface.
> 
> Note that this is the interface for operations.  There will be
> a separate interface (most likely netlink) for configuring crypto
> algorithms, e.g., picking a specific AES implementation as the
> system default.

OK I've gone ahead and implemented the user-space API for hashes
and ciphers.

To recap this interface is designed to allow user-space programs
to access hardware cryptographic accelerators that we have added
to the kernel.

The intended usage scenario is where a large amount of data needs
to be processed where the benefits offered by hardware acceleration
that is normally unavailable in user-space (as opposed to ones
such as the Intel AES instruction which may be used directly from
user-space) outweigh the overhead of going through the kernel.

In order to further minimise the overhead in these cases, this
interface offers the option of avoiding copying data between
user-space and the kernel where possible and appropriate.  For
ciphers this means the use of the splice(2) interface instead of
sendmsg(2)

Here is a sample hash program (note that these only illustrate
what the interface looks like and are not meant to be good examples
of coding :)

int main(void)
{
	int opfd;
	int tfmfd;
	struct sockaddr_alg sa = {
		.salg_family = AF_ALG,
		.salg_type = "hash",
		.salg_name = "sha1"
	};
	char buf[20];
	int i;

	tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0);

	bind(tfmfd, (struct sockaddr *)&sa, sizeof(sa));

	opfd = accept(tfmfd, NULL, 0);

	write(opfd, "abc", 3);
	read(opfd, buf, 20);

	for (i = 0; i < 20; i++) {
		printf("%02x", (unsigned char)buf[i]);
	}
	printf("\n");

	close(opfd);
	close(tfmfd);

	return 0;
}

And here is one for ciphers:

int main(void)
{
	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)];
	char buf[16];
	struct af_alg_iv *iv;
	struct iovec iov;
	int i;

	tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0);

	bind(tfmfd, (struct sockaddr *)&sa, sizeof(sa));

	setsockopt(tfmfd, SOL_ALG, ALG_SET_KEY,
		   "\x06\xa9\x21\x40\x36\xb8\xa1\x5b"
		   "\x51\x2e\x03\xd5\x34\x12\x00\x06", 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->ivlen = 16;
	memcpy(iv->iv, "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30"
		       "\xb4\x22\xda\x80\x2c\x9f\xac\x41", 16);

	iov.iov_base = "Single block msg";
	iov.iov_len = 16;

	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;

	sendmsg(opfd, &msg, 0);
	read(opfd, buf, 16);

	for (i = 0; i < 16; i++) {
		printf("%02x", (unsigned char)buf[i]);
	}
	printf("\n");

	close(opfd);
	close(tfmfd);

	return 0;
}

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

* Re: RFC: Crypto API User-interface
  2010-10-19 13:44 ` Herbert Xu
@ 2010-10-20 10:24   ` Nikos Mavrogiannopoulos
  2010-11-04 17:34   ` Herbert Xu
  1 sibling, 0 replies; 20+ messages in thread
From: Nikos Mavrogiannopoulos @ 2010-10-20 10:24 UTC (permalink / raw)
  To: Herbert Xu
  Cc: Linux Crypto Mailing List, netdev, Linux Kernel Mailing List,
	Cryptodev-linux-devel

On Tue, Oct 19, 2010 at 3:44 PM, Herbert Xu
<herbert@gondor.hengli.com.au> wrote:
> OK I've gone ahead and implemented the user-space API for hashes
> and ciphers.
> To recap this interface is designed to allow user-space programs
> to access hardware cryptographic accelerators that we have added
> to the kernel.
> The intended usage scenario is where a large amount of data needs
> to be processed where the benefits offered by hardware acceleration
> that is normally unavailable in user-space (as opposed to ones
> such as the Intel AES instruction which may be used directly from
> user-space) outweigh the overhead of going through the kernel.

What is the overall advantage of this API comparing to other existing
ones that achieve similar goals[0][1]?

Some observations:
1. To perform an encryption of data 6 system calls are made (I don't
count the 2 used for socket initialization since I suppose can be global
for all operations) and a file descriptor is assigned. The number of
system calls
made has great impact to the actual speed seen by userspace (as you said this
API is for user-space to access the high-speed peripherals that do encryption).
2. Due to the usage of read() and write() no zero-copy can happen for
user-space buffers[3].

regards,
Nikos

[0]. http://home.gna.org/cryptodev-linux/
[1]. http://home.gna.org/cryptodev-linux/ncr.html
[2]. The openbsd[0] api can do it with 3 system calls and NCR[1] with one,
and both require no file descriptor for each operation.
[3]. The openbsd[0] api and NCR[1] do zero-copy for user-space buffers.

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

* Re: RFC: Crypto API User-interface
  2010-10-19 13:44 ` Herbert Xu
  2010-10-20 10:24   ` Nikos Mavrogiannopoulos
@ 2010-11-04 17:34   ` Herbert Xu
  1 sibling, 0 replies; 20+ messages in thread
From: Herbert Xu @ 2010-11-04 17:34 UTC (permalink / raw)
  To: Linux Crypto Mailing List, netdev, Linux Kernel Mailing List

On Tue, Oct 19, 2010 at 09:44:18PM +0800, Herbert Xu wrote:
> 
> OK I've gone ahead and implemented the user-space API for hashes
> and ciphers.

Here is a revised series with bug fixes and improvements.  The
main change is that hashes can now be finalised by recvmsg instead
of requiring a preceding sendmsg with no MSG_MORE.

Thakns to Miloslav Trmac for reviewing this and contributing
fixes and improvements.

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

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

end of thread, other threads:[~2010-11-04 17:34 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <834983542.1086561283871074929.JavaMail.root@zmail07.collab.prod.int.phx2.redhat.com>
2010-09-07 14:52 ` RFC: Crypto API User-interface Miloslav Trmac
2010-09-07 14:55   ` Christoph Hellwig
     [not found] <1847066281.1081601283869883727.JavaMail.root@zmail07.collab.prod.int.phx2.redhat.com>
2010-09-07 14:34 ` Miloslav Trmac
2010-09-07 14:41   ` Herbert Xu
2010-09-07 14:51   ` Christoph Hellwig
2010-09-07 14:54     ` Miloslav Trmac
     [not found] <1590523029.1055831283858598965.JavaMail.root@zmail07.collab.prod.int.phx2.redhat.com>
2010-09-07 11:27 ` Miloslav Trmac
2010-09-07 14:07   ` Herbert Xu
2010-09-07  8:42 Herbert Xu
2010-09-07  9:18 ` Tomas Mraz
2010-09-07 14:06 ` Christoph Hellwig
2010-09-07 14:11   ` Herbert Xu
2010-09-07 14:24     ` Christoph Hellwig
2010-09-07 14:39       ` Herbert Xu
2010-09-07 14:49     ` Nikos Mavrogiannopoulos
2010-09-07 14:57   ` Nikos Mavrogiannopoulos
2010-09-07 14:59     ` Christoph Hellwig
2010-10-19 13:44 ` Herbert Xu
2010-10-20 10:24   ` Nikos Mavrogiannopoulos
2010-11-04 17:34   ` Herbert Xu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).