From: Herbert Xu <herbert@gondor.apana.org.au> Date: 2010-09-07 08:42:13
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 [off-list ref]
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
From: Tomas Mraz <hidden> Date: 2010-09-07 09:18:53
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
From: Christoph Hellwig <hch@infradead.org> Date: 2010-09-07 14:06:50
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.
From: Herbert Xu <hidden> Date: 2010-09-07 14:11:19
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:
quoted
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 [off-list ref]
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
From: Christoph Hellwig <hch@infradead.org> Date: 2010-09-07 14:24:31
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.
From: Herbert Xu <hidden> Date: 2010-09-07 14:39:10
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).
quoted
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.
On Tue, Sep 7, 2010 at 4:11 PM, Herbert Xu [off-list ref] wrote:
quoted
quoted
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
On Tue, Sep 7, 2010 at 4:06 PM, Christoph Hellwig [off-list ref] wrote:
quoted
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
From: Christoph Hellwig <hch@infradead.org> Date: 2010-09-07 14:59:45
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.
From: Herbert Xu <hidden> Date: 2010-10-19 13:44:22
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 [off-list ref]
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
From: Herbert Xu <hidden> Date: 2010-10-19 13:46:06
net - Add AF_ALG macros
This patch adds the socket family/level macros for the yet-to-be-born
AF_ALG family. The AF_ALG family provides the user-space interface
for the kernel crypto API.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---
include/linux/socket.h | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
From: Herbert Xu <hidden> Date: 2010-10-19 13:46:11
crypto: algif_skcipher - User-space interface for skcipher operations
This patch adds the af_alg plugin for symmetric key ciphers,
corresponding to the ablkcipher kernel operation type.
Keys can optionally be set through the setsockopt interface.
Once a sendmsg call occurs without MSG_MORE no further writes
may be made to the socket until all previous data has been read.
IVs and and whether encryption/decryption is performed can be
set through the setsockopt interface or as a control message
to sendmsg.
The interface is completely synchronous, all operations are
carried out in recvmsg(2) and will complete prior to the system
call returning.
The splice(2) interface support reading the user-space data directly
without copying (except that the Crypto API itself may copy the data
if alignment is off).
The recvmsg(2) interface supports directly writing to user-space
without additional copying, i.e., the kernel crypto interface will
receive the user-space address as its output SG list.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---
crypto/Kconfig | 8
crypto/Makefile | 1
crypto/algif_skcipher.c | 664 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 673 insertions(+)
@@ -87,6 +87,7 @@ obj-$(CONFIG_CRYPTO_TEST) += tcrypt.oobj-$(CONFIG_CRYPTO_GHASH)+=ghash-generic.oobj-$(CONFIG_CRYPTO_USER_API)+=af_alg.oobj-$(CONFIG_CRYPTO_USER_API_HASH)+=algif_hash.o+obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER)+=algif_skcipher.o## generic algorithms and the async_tx api
From: Herbert Xu <hidden> Date: 2010-10-19 13:46:12
crypto: algif_hash - User-space interface for hash operations
This patch adds the af_alg plugin for hash, corresponding to
the ahash kernel operation type.
Keys can optionally be set through the setsockopt interface.
Each sendmsg call will finalise the hash unless sent with a MSG_MORE
flag.
Partial hash states can be cloned using accept(2).
The interface is completely synchronous, all operations will
complete prior to the system call returning.
Both sendmsg(2) and splice(2) support reading the user-space
data directly without copying (except that the Crypto API itself
may copy the data if alignment is off).
For now only the splice(2) interface supports performing digest
instead of init/update/final. In future the sendmsg(2) interface
will also be modified to use digest/finup where possible so that
hardware that cannot return a partial hash state can still benefit
from this interface.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---
crypto/Kconfig | 8 +
crypto/Makefile | 1
crypto/algif_hash.c | 345 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 354 insertions(+)
@@ -86,6 +86,7 @@ obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.oobj-$(CONFIG_CRYPTO_TEST)+=tcrypt.oobj-$(CONFIG_CRYPTO_GHASH)+=ghash-generic.oobj-$(CONFIG_CRYPTO_USER_API)+=af_alg.o+obj-$(CONFIG_CRYPTO_USER_API_HASH)+=algif_hash.o## generic algorithms and the async_tx api
From: Herbert Xu <hidden> Date: 2010-10-19 13:46:44
crypto: af_alg - User-space interface for Crypto API
This patch creates the backbone of the user-space interface for
the Crypto API, through a new socket family AF_ALG.
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.
Each algorithm type will provide its own implementation that plugs
into af_alg. They're keyed using a string such as "skcipher" or
"hash".
IOW this patch only contains the boring bits that is required
to hold everything together.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---
crypto/Kconfig | 3
crypto/Makefile | 1
crypto/af_alg.c | 433 ++++++++++++++++++++++++++++++++++++++++++++++++
include/crypto/if_alg.h | 75 ++++++++
include/linux/if_alg.h | 40 ++++
5 files changed, 552 insertions(+)
@@ -85,6 +85,7 @@ obj-$(CONFIG_CRYPTO_RNG2) += krng.oobj-$(CONFIG_CRYPTO_ANSI_CPRNG)+=ansi_cprng.oobj-$(CONFIG_CRYPTO_TEST)+=tcrypt.oobj-$(CONFIG_CRYPTO_GHASH)+=ghash-generic.o+obj-$(CONFIG_CRYPTO_USER_API)+=af_alg.o## generic algorithms and the async_tx api
@@ -0,0 +1,75 @@+/*+*if_alg:User-spacealgorithminterface+*+*Copyright(c)2010HerbertXu<herbert@gondor.apana.org.au>+*+*Thisprogramisfreesoftware;youcanredistributeitand/ormodifyit+*underthetermsoftheGNUGeneralPublicLicenseaspublishedbytheFree+*SoftwareFoundation;eitherversion2oftheLicense,or(atyouroption)+*anylaterversion.+*+*/++#ifndef _CRYPTO_IF_ALG_H+#define _CRYPTO_IF_ALG_H++#include<linux/compiler.h>+#include<linux/if_alg.h>+#include<linux/types.h>+#include<net/sock.h>++#define ALG_MAX_PAGES 16++structalg_sock{+/* struct sock must be the first member of struct alg_sock */+structsocksk;++structsock*parent;++conststructaf_alg_type*type;+void*private;+};++structaf_alg_control{+structaf_alg_iv*iv;+intop;+};++structaf_alg_type{+void*(*bind)(constchar*name,u32type,u32mask);+void(*release)(void*private);+int(*setkey)(void*private,constu8*key,unsignedintkeylen);+int(*accept)(void*private,structsock*sk);++structproto_ops*ops;+structmodule*owner;+charname[14];+};++structaf_alg_sgl{+structscatterlistsg[ALG_MAX_PAGES];+structpage*pages[ALG_MAX_PAGES];+};++intaf_alg_register_type(conststructaf_alg_type*type);+intaf_alg_unregister_type(conststructaf_alg_type*type);++intaf_alg_release(structsocket*sock);+intaf_alg_accept(structsock*sk,structsocket*newsock);++intaf_alg_make_sg(structaf_alg_sgl*sgl,void*addr,intlen,intwrite);+voidaf_alg_free_sg(structaf_alg_sgl*sgl);++intaf_alg_cmsg_send(structmsghdr*msg,structaf_alg_control*con);++staticinlinestructalg_sock*alg_sk(structsock*sk)+{+return(structalg_sock*)sk;+}++staticinlinevoidaf_alg_release_parent(structsock*sk)+{+sock_put(alg_sk(sk)->parent);+}++#endif /* _CRYPTO_IF_ALG_H */
From: David Miller <davem@davemloft.net> Date: 2010-10-20 09:01:21
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Tue, 19 Oct 2010 21:46:01 +0800
net - Add AF_ALG macros
This patch adds the socket family/level macros for the yet-to-be-born
AF_ALG family. The AF_ALG family provides the user-space interface
for the kernel crypto API.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
On Tue, Oct 19, 2010 at 3:44 PM, Herbert Xu
[off-list ref] 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.
From: Herbert Xu <hidden> Date: 2010-11-04 17:35:01
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 [off-list ref]
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
From: Herbert Xu <hidden> Date: 2010-11-04 17:36:22
net - Add AF_ALG macros
This patch adds the socket family/level macros for the yet-to-be-born
AF_ALG family. The AF_ALG family provides the user-space interface
for the kernel crypto API.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---
include/linux/socket.h | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
From: Herbert Xu <hidden> Date: 2010-11-04 17:36:26
crypto: af_alg - User-space interface for Crypto API
This patch creates the backbone of the user-space interface for
the Crypto API, through a new socket family AF_ALG.
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.
Each algorithm type will provide its own implementation that plugs
into af_alg. They're keyed using a string such as "skcipher" or
"hash".
IOW this patch only contains the boring bits that is required
to hold everything together.
Thakns to Miloslav Trmac for reviewing this and contributing
fixes and improvements.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---
crypto/Kconfig | 3
crypto/Makefile | 1
crypto/af_alg.c | 460 ++++++++++++++++++++++++++++++++++++++++++++++++
include/crypto/if_alg.h | 92 +++++++++
include/linux/if_alg.h | 40 ++++
5 files changed, 596 insertions(+)
@@ -85,6 +85,7 @@ obj-$(CONFIG_CRYPTO_RNG2) += krng.oobj-$(CONFIG_CRYPTO_ANSI_CPRNG)+=ansi_cprng.oobj-$(CONFIG_CRYPTO_TEST)+=tcrypt.oobj-$(CONFIG_CRYPTO_GHASH)+=ghash-generic.o+obj-$(CONFIG_CRYPTO_USER_API)+=af_alg.o## generic algorithms and the async_tx api
@@ -0,0 +1,92 @@+/*+*if_alg:User-spacealgorithminterface+*+*Copyright(c)2010HerbertXu<herbert@gondor.apana.org.au>+*+*Thisprogramisfreesoftware;youcanredistributeitand/ormodifyit+*underthetermsoftheGNUGeneralPublicLicenseaspublishedbytheFree+*SoftwareFoundation;eitherversion2oftheLicense,or(atyouroption)+*anylaterversion.+*+*/++#ifndef _CRYPTO_IF_ALG_H+#define _CRYPTO_IF_ALG_H++#include<linux/compiler.h>+#include<linux/completion.h>+#include<linux/if_alg.h>+#include<linux/types.h>+#include<net/sock.h>++#define ALG_MAX_PAGES 16++structcrypto_async_request;++structalg_sock{+/* struct sock must be the first member of struct alg_sock */+structsocksk;++structsock*parent;++conststructaf_alg_type*type;+void*private;+};++structaf_alg_completion{+structcompletioncompletion;+interr;+};++structaf_alg_control{+structaf_alg_iv*iv;+intop;+};++structaf_alg_type{+void*(*bind)(constchar*name,u32type,u32mask);+void(*release)(void*private);+int(*setkey)(void*private,constu8*key,unsignedintkeylen);+int(*accept)(void*private,structsock*sk);++structproto_ops*ops;+structmodule*owner;+charname[14];+};++structaf_alg_sgl{+structscatterlistsg[ALG_MAX_PAGES];+structpage*pages[ALG_MAX_PAGES];+};++intaf_alg_register_type(conststructaf_alg_type*type);+intaf_alg_unregister_type(conststructaf_alg_type*type);++intaf_alg_release(structsocket*sock);+intaf_alg_accept(structsock*sk,structsocket*newsock);++intaf_alg_make_sg(structaf_alg_sgl*sgl,void__user*addr,intlen,+intwrite);+voidaf_alg_free_sg(structaf_alg_sgl*sgl);++intaf_alg_cmsg_send(structmsghdr*msg,structaf_alg_control*con);++intaf_alg_wait_for_completion(interr,structaf_alg_completion*completion);+voidaf_alg_complete(structcrypto_async_request*req,interr);++staticinlinestructalg_sock*alg_sk(structsock*sk)+{+return(structalg_sock*)sk;+}++staticinlinevoidaf_alg_release_parent(structsock*sk)+{+sock_put(alg_sk(sk)->parent);+}++staticinlinevoidaf_alg_init_completion(structaf_alg_completion*completion)+{+init_completion(&completion->completion);+}++#endif /* _CRYPTO_IF_ALG_H */
From: Herbert Xu <hidden> Date: 2010-11-04 17:36:42
crypto: algif_skcipher - User-space interface for skcipher operations
This patch adds the af_alg plugin for symmetric key ciphers,
corresponding to the ablkcipher kernel operation type.
Keys can optionally be set through the setsockopt interface.
Once a sendmsg call occurs without MSG_MORE no further writes
may be made to the socket until all previous data has been read.
IVs and and whether encryption/decryption is performed can be
set through the setsockopt interface or as a control message
to sendmsg.
The interface is completely synchronous, all operations are
carried out in recvmsg(2) and will complete prior to the system
call returning.
The splice(2) interface support reading the user-space data directly
without copying (except that the Crypto API itself may copy the data
if alignment is off).
The recvmsg(2) interface supports directly writing to user-space
without additional copying, i.e., the kernel crypto interface will
receive the user-space address as its output SG list.
Thakns to Miloslav Trmac for reviewing this and contributing
fixes and improvements.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---
crypto/Kconfig | 8
crypto/Makefile | 1
crypto/algif_skcipher.c | 647 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 656 insertions(+)
@@ -87,6 +87,7 @@ obj-$(CONFIG_CRYPTO_TEST) += tcrypt.oobj-$(CONFIG_CRYPTO_GHASH)+=ghash-generic.oobj-$(CONFIG_CRYPTO_USER_API)+=af_alg.oobj-$(CONFIG_CRYPTO_USER_API_HASH)+=algif_hash.o+obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER)+=algif_skcipher.o## generic algorithms and the async_tx api
From: Herbert Xu <hidden> Date: 2010-11-04 17:36:45
crypto: algif_hash - User-space interface for hash operations
This patch adds the af_alg plugin for hash, corresponding to
the ahash kernel operation type.
Keys can optionally be set through the setsockopt interface.
Each sendmsg call will finalise the hash unless sent with a MSG_MORE
flag.
Partial hash states can be cloned using accept(2).
The interface is completely synchronous, all operations will
complete prior to the system call returning.
Both sendmsg(2) and splice(2) support reading the user-space
data directly without copying (except that the Crypto API itself
may copy the data if alignment is off).
For now only the splice(2) interface supports performing digest
instead of init/update/final. In future the sendmsg(2) interface
will also be modified to use digest/finup where possible so that
hardware that cannot return a partial hash state can still benefit
from this interface.
Thakns to Miloslav Trmac for reviewing this and contributing
fixes and improvements.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---
crypto/Kconfig | 8 +
crypto/Makefile | 1
crypto/algif_hash.c | 321 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 330 insertions(+)
@@ -86,6 +86,7 @@ obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.oobj-$(CONFIG_CRYPTO_TEST)+=tcrypt.oobj-$(CONFIG_CRYPTO_GHASH)+=ghash-generic.oobj-$(CONFIG_CRYPTO_USER_API)+=af_alg.o+obj-$(CONFIG_CRYPTO_USER_API_HASH)+=algif_hash.o## generic algorithms and the async_tx api
From: David Miller <davem@davemloft.net> Date: 2010-11-04 19:22:13
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Thu, 04 Nov 2010 12:36:19 -0500
net - Add AF_ALG macros
This patch adds the socket family/level macros for the yet-to-be-born
AF_ALG family. The AF_ALG family provides the user-space interface
for the kernel crypto API.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
From: David Miller <davem@davemloft.net> Date: 2010-11-04 19:22:42
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Thu, 04 Nov 2010 12:36:19 -0500
crypto: af_alg - User-space interface for Crypto API
This patch creates the backbone of the user-space interface for
the Crypto API, through a new socket family AF_ALG.
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.
Each algorithm type will provide its own implementation that plugs
into af_alg. They're keyed using a string such as "skcipher" or
"hash".
IOW this patch only contains the boring bits that is required
to hold everything together.
Thakns to Miloslav Trmac for reviewing this and contributing
fixes and improvements.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
From: David Miller <davem@davemloft.net> Date: 2010-11-04 19:22:58
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Thu, 04 Nov 2010 12:36:19 -0500
crypto: algif_hash - User-space interface for hash operations
This patch adds the af_alg plugin for hash, corresponding to
the ahash kernel operation type.
Keys can optionally be set through the setsockopt interface.
Each sendmsg call will finalise the hash unless sent with a MSG_MORE
flag.
Partial hash states can be cloned using accept(2).
The interface is completely synchronous, all operations will
complete prior to the system call returning.
Both sendmsg(2) and splice(2) support reading the user-space
data directly without copying (except that the Crypto API itself
may copy the data if alignment is off).
For now only the splice(2) interface supports performing digest
instead of init/update/final. In future the sendmsg(2) interface
will also be modified to use digest/finup where possible so that
hardware that cannot return a partial hash state can still benefit
from this interface.
Thakns to Miloslav Trmac for reviewing this and contributing
fixes and improvements.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
From: David Miller <davem@davemloft.net> Date: 2010-11-04 19:23:21
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Thu, 04 Nov 2010 12:36:20 -0500
crypto: algif_skcipher - User-space interface for skcipher operations
This patch adds the af_alg plugin for symmetric key ciphers,
corresponding to the ablkcipher kernel operation type.
Keys can optionally be set through the setsockopt interface.
Once a sendmsg call occurs without MSG_MORE no further writes
may be made to the socket until all previous data has been read.
IVs and and whether encryption/decryption is performed can be
set through the setsockopt interface or as a control message
to sendmsg.
The interface is completely synchronous, all operations are
carried out in recvmsg(2) and will complete prior to the system
call returning.
The splice(2) interface support reading the user-space data directly
without copying (except that the Crypto API itself may copy the data
if alignment is off).
The recvmsg(2) interface supports directly writing to user-space
without additional copying, i.e., the kernel crypto interface will
receive the user-space address as its output SG list.
Thakns to Miloslav Trmac for reviewing this and contributing
fixes and improvements.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>