Crypto kernel TLS socket
Subsystems (4)
cover Crypto kernel TLS socket
An approach for a kernel TLS socket.
Only the symmetric encryption / decryption is done in-kernel, as well as minimal framing handling. The handshake is kept in userspace, and the negotiated cipher / keys / IVs are then set on the algif_tls socket, which is then hooked in to a tcp socket using sk_write_space/sk_data_ready hooks.
If a non application-data TLS record is seen, it is left on the TCP socket and an error is returned on the ALG socket, and the record is left for userspace to manage. Userspace can't ignore the message, but could just close the socket.
TLS could potentially also be done directly on the TCP socket, but seemed a bit harder to work with the OOB data for non application_data messages, and the sockopts / CMSGS already exist for ALG sockets. The flip side is having to manage two fds in userspace.
Some reasons we're looking at this:
1) Access to sendfile/splice for CDN-type applications. We were inspired by Netflix exploring this in FreeBSD
https://people.freebsd.org/~rrs/asiabsd_2015_tls.pdf
For perf, this patch is almost on par with userspace OpenSSL. Currently there are some copies and allocs to support scatter/gather in aesni-intel_glue.c, but with some extra work to remove those (not included here), a sendfile() is faster than the equivalent userspace read/SSL_write using a 128k buffer by 2~7%.
2) Access to the unencrypted bytes in kernelspace. For example, Tom Herbert's kcm would need this
https://lwn.net/Articles/657999/
3) NIC offload. To support running aesni routines on the NIC instead of the processor, we would probably need enough of the framing interface put in kernel.
Dave Watson (2):
Crypto support aesni rfc5288
Crypto kernel tls socket
arch/x86/crypto/aesni-intel_asm.S | 6 + arch/x86/crypto/aesni-intel_avx-x86_64.S | 4 + arch/x86/crypto/aesni-intel_glue.c | 105 ++- crypto/Kconfig | 12 + crypto/Makefile | 1 + crypto/algif_tls.c | 1233 ++++++++++++++++++++++++++++++ 6 files changed, 1334 insertions(+), 27 deletions(-) create mode 100644 crypto/algif_tls.c
--
2.4.6
RFC PATCH 1/2 Crypto support aesni rfc5288
Support rfc5288 using intel aesni routines. See also rfc5246.
AAD length is 13 bytes padded out to 16. Padding bytes have to be passed in in scatterlist currently, which probably isn't quite the right fix.
The assoclen checks were moved to the individual rfc stubs, and the common routines support all assoc lengths.
--- arch/x86/crypto/aesni-intel_asm.S | 6 ++ arch/x86/crypto/aesni-intel_avx-x86_64.S | 4 ++ arch/x86/crypto/aesni-intel_glue.c | 105 +++++++++++++++++++++++-------- 3 files changed, 88 insertions(+), 27 deletions(-)
arch/x86/crypto/aesni-intel_asm.S +6 -0
@@ -228,6 +228,9 @@ XMM2 XMM3 XMM4 XMMDst TMP6 TMP7 i i_seq operation MOVADQ SHUF_MASK(%rip), %xmm14 mov arg7, %r10 # %r10 = AAD mov arg8, %r12 # %r12 = aadLen + add $3, %r12 + and $~3, %r12 + mov %r12, %r11 pxor %xmm\i, %xmm\i
@@ -453,6 +456,9 @@ XMM2 XMM3 XMM4 XMMDst TMP6 TMP7 i i_seq operation MOVADQ SHUF_MASK(%rip), %xmm14 mov arg7, %r10 # %r10 = AAD mov arg8, %r12 # %r12 = aadLen + add $3, %r12 + and $~3, %r12 + mov %r12, %r11 pxor %xmm\i, %xmm\i _get_AAD_loop\num_initial_blocks\operation:
arch/x86/crypto/aesni-intel_avx-x86_64.S +4 -0
@@ -360,6 +360,8 @@ VARIABLE_OFFSET = 16*8 mov arg6, %r10 # r10 = AAD mov arg7, %r12 # r12 = aadLen + add $3, %r12 + and $~3, %r12 mov %r12, %r11
@@ -1619,6 +1621,8 @@ ENDPROC(aesni_gcm_dec_avx_gen2) mov arg6, %r10 # r10 = AAD mov arg7, %r12 # r12 = aadLen + add $3, %r12 + and $~3, %r12 mov %r12, %r11
arch/x86/crypto/aesni-intel_glue.c +78 -27
191 lines not on this page · raw message
--
2.4.6
Herbert Xu
maintainerRe: [RFC PATCH 1/2] Crypto support aesni rfc5288
Quoted 8 lines · Dave Watson
Support rfc5288 using intel aesni routines. See also rfc5246.
AAD length is 13 bytes padded out to 16. Padding bytes have to be passed in in scatterlist currently, which probably isn't quite the right fix.
The assoclen checks were moved to the individual rfc stubs, and the common routines support all assoc lengths.
I know this is just an RFC. But if we were going to add an rfc5288 template then you should add a C version first, then followed by the aesni optimised version.
Thanks,
Signature · 3 lines
Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
RFC PATCH 2/2 Crypto kernel tls socket
In reply to Dave WatsonUserspace crypto interface for TLS. Currently supports gcm(aes) 128bit only, however the interface is the same as the rest of the SOCK_ALG interface, so it should be possible to add more without any user interface changes.
Currently gcm(aes) represents ~80% of our SSL connections.
Userspace interface:
1) A transform and op socket are created using the userspace crypto interface
2) Setsockopt ALG_SET_AUTHSIZE is called
3) Setsockopt ALG_SET_KEY is called twice, since we need both send/recv keys
4) ALG_SET_IV cmsgs are sent twice, since we need both send/recv IVs. To support userspace heartbeats, changeciphersuite, etc, we would also need to get these back out, use them, then reset them via CMSG.
5) ALG_SET_OP cmsg is overloaded to mean FD to read/write from.
Example program:
https://github.com/djwatson/ktls
At a high level, this could be implemented on TCP sockets directly instead with various tradeoffs.
The userspace crypto interface might benefit from some interface tweaking to deal with multiple keys / ivs better. The crypto accept() op socket interface isn't a great fit, since there are never multiple parallel operations.
There's also some questions around using skbuffs instead of scatterlists for send/recv, and if we are buffering on recv, when we should be decrypting the data.
--- crypto/Kconfig | 12 + crypto/Makefile | 1 + crypto/algif_tls.c | 1233 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1246 insertions(+) create mode 100644 crypto/algif_tls.c
crypto/Kconfig +12 -0
@@ -1639,6 +1639,18 @@ config CRYPTO_USER_API_AEAD This option enables the user-spaces interface for AEAD cipher algorithms. +config CRYPTO_USER_API_TLS + tristate "User-space interface for TLS net sockets" + depends on NET + select CRYPTO_AEAD + select CRYPTO_USER_API + help + This option enables kernel TLS socket framing + cipher algorithms. TLS framing is added/removed and + chained to a TCP socket. Handshake is done in + userspace. + + config CRYPTO_HASH_INFO bool
crypto/Makefile +1 -0
@@ -121,6 +121,7 @@ obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o obj-$(CONFIG_CRYPTO_USER_API_RNG) += algif_rng.o obj-$(CONFIG_CRYPTO_USER_API_AEAD) += algif_aead.o +obj-$(CONFIG_CRYPTO_USER_API_TLS) += algif_tls.o # # generic algorithms and the async_tx api
crypto/algif_tls.c new file +1233 -0
1,233 lines not on this page · raw message
--
2.4.6
Re: [RFC PATCH 2/2] Crypto kernel tls socket
Quoted 11 lines · Dave Watson
Currently gcm(aes) represents ~80% of our SSL connections.
Userspace interface:
1) A transform and op socket are created using the userspace crypto interface
2) SetsockoptALG_SET_AUTHSIZEis called
3) SetsockoptALG_SET_KEYis called twice, since we need both send/recv keys
4)ALG_SET_IVcmsgs are sent twice, since we need both send/recv IVs. To support userspace heartbeats, changeciphersuite, etc, we would also need to get these back out, use them, then reset them via CMSG.
5)ALG_SET_OPcmsg is overloaded to mean FD to read/write from.
[from patch 0/2:]
Quoted 3 lines
If a non application-data TLS record is seen, it is left on the TCP socket and an error is returned on the ALG socket, and the record is left for userspace to manage.
Interesting approach.
FWIW, I was hoping to discuss solutions for securing traffic tunnelled over L3 at netdev 1.1, so hopefully we'll be able to go over the trade-offs there.
I'm trying to see how your approach would fit with the RDS-type of use-case. RDS-TCP is mostly similar in concept to kcm, except that rds has its own header for multiplexing, and has no dependancy on BPF for basic things like re-assembling the datagram. If I were to try to use this for RDS-TCP, the tls_tcp_read_sock() logic would be merged into the recv_actor callback for RDS, right? Thus tls control-plane message could be seen in the middle of the data-stream, so we really have to freeze the processing of the data stream till the control-plane message is processed?
I'm concerned about the possiblilites for async that can happen when we separate the data-plane from the control-plane (uspace tls does not have to deal with this), but we now have control plane separated from data-plane. (And IPsec/IKE has plenty of headaches from this sort of thing already)
In the tls.c example that you have, the opfd is generated from the accept() on the AF_ALG socket- how would this work if I wanted my opfd to be a PF_RDS or a PF_KCM or similar?
One concern is that this patchset provides a solution for the "80%" case but what about the other 20% (and the non x86 platforms)? E.g., if I get a cipher-suite request outside the aes-ni, what would happen (punt to uspace?)
--Sowmini
Re: [RFC PATCH 2/2] Crypto kernel tls socket
Quoted 18 lines · Sowmini Varadhan
Quoted 11 lines · Dave Watson
Currently gcm(aes) represents ~80% of our SSL connections.
Userspace interface:
1) A transform and op socket are created using the userspace crypto interface
2) SetsockoptALG_SET_AUTHSIZEis called
3) SetsockoptALG_SET_KEYis called twice, since we need both send/recv keys
4)ALG_SET_IVcmsgs are sent twice, since we need both send/recv IVs. To support userspace heartbeats, changeciphersuite, etc, we would also need to get these back out, use them, then reset them via CMSG.
5)ALG_SET_OPcmsg is overloaded to mean FD to read/write from.[from patch 0/2:]
Quoted 3 lines
If a non application-data TLS record is seen, it is left on the TCP socket and an error is returned on the ALG socket, and the record is left for userspace to manage.
Quoted 9 lines
I'm trying to see how your approach would fit with the RDS-type of use-case. RDS-TCP is mostly similar in concept to kcm, except that rds has its own header for multiplexing, and has no dependancy on BPF for basic things like re-assembling the datagram. If I were to try to use this for RDS-TCP, the
tls_tcp_read_sock()logic would be merged into therecv_actorcallback for RDS, right? Thus tls control-plane message could be seen in the middle of the data-stream, so we really have to freeze the processing of the data stream till the control-plane message is processed?
Correct.
Quoted 3 lines
In the
tls.cexample that you have, the opfd is generated from theaccept()on theAF_ALGsocket- how would this work if I wanted my opfd to be aPF_RDSor aPF_KCMor similar?
For kcm, opfd is the fd you would pass along in kcm_attach.
For rds, it looks like you'd want to use opfd as the sock instead of the new one created by sock_create_kern in rds_tcp_conn_connect.
Quoted 2 lines
One concern is that this patchset provides a solution for the "80%" case but what about the other 20% (and the non x86 platforms)?
Almost all the rest are aes sha. The actual encrypt / decrypt code would be similar to this previous patch:
http://marc.info/?l=linux-kernel&m=140662647602192&w=2
The software routines in gcm(aes) should work for all platforms without aesni.
Quoted 4 lines
E.g., if I get a cipher-suite request outside the aes-ni, what would happen (punt to uspace?)
--Sowmini
Right, bind() would fail and you would fallback to uspace.
Re: [RFC PATCH 2/2] Crypto kernel tls socket
Quoted 4 lines · Dave Watson
For kcm, opfd is the fd you would pass along in
kcm_attach. For rds, it looks like you'd want to use opfd as the sock instead of the new one created bysock_create_kerninrds_tcp_conn_connect.
I see.
It's something to consider, and it would certainly secure the RDS header and app data, but TLS by itself may not be enough- we'd need to protect the TCP control plane as well, and at the moment, I'm finding that even using esp-null (or AO, or MD5, for that matter) means that I lose GSO, and perf tanks. I'll try to put all my data together for this for netdev 1.1.
Quoted 6 lines
Quoted 4 lines
E.g., if I get a cipher-suite request outside the aes-ni, what would happen (punt to uspace?)
--Sowmini
Right,
bind()would fail and you would fallback to uspace.
That's the approach that Solaris KSSL took, back in 1999. It quickly became obsolete, again more details in netdev 1.1.
--Sowmini
Herbert Xu
maintainerRe: [RFC PATCH 2/2] Crypto kernel tls socket
In reply to Dave WatsonQuoted 3 lines · Dave Watson
Userspace crypto interface for TLS. Currently supports gcm(aes) 128bit only, however the interface is the same as the rest of the
SOCK_ALGinterface, so it should be possible to add more without any user interface changes.
SOCK_ALG exists to export crypto algorithms to user-space. So if we decided to support TLS as an algorithm then I guess this makes sense.
However, I must say that it wouldn't have been my first pick. I'd imagine a TLS socket to look more like a TCP socket, or perhaps a KCM socket as proposed by Tom.
Thanks,
Signature · 3 lines
Email: Herbert Xu <[email protected]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Re: [RFC PATCH 2/2] Crypto kernel tls socket
Am Dienstag, 24. November 2015, 18:34:55 schrieb Herbert Xu:
Hi Herbert,
Quoted 6 lines · Dave Watson
Quoted 4 lines
Userspace crypto interface for TLS. Currently supports gcm(aes) 128bit only, however the interface is the same as the rest of the
SOCK_ALGinterface, so it should be possible to add more without any user interface changes.
Quoted 7 lines
SOCK_ALGexists to export crypto algorithms to user-space. So if we decided to support TLS as an algorithm then I guess this makes sense.However, I must say that it wouldn't have been my first pick. I'd imagine a TLS socket to look more like a TCP socket, or perhaps a KCM socket as proposed by Tom.
If I may ask: what is the benefit of having TLS in kernel space? I do not see any reason why higher-level protocols should be in the kernel as they do not relate to accessing hardware.
The only reason I could fathom is to keep the negotiated keys in a secure realm. But that could be done without having parts or the whole TLS protocol stack in the kernel. If the key management should stay in the kernel as a protection domain, I would rather think that the kernel should offer a plug- and-play of raw ciphers where user space is responsible to form a protocol. This way, we do not limit such key management to TLS, but allow any kind of protocol to use it.
E.g. the kernel performs the key transport with RSA or key agreement with DH using keyring-based key material. The resulting shared secret is again maintained in the key ring where user space can use the symmetric ciphers of the kernel with those keys. User space would only see references to keys but no real keys. However, only user space knows when to invoke what cipher to implement a specific protocol.
Ciao
Stephan
Re: [RFC PATCH 2/2] Crypto kernel tls socket
Hello,
Quoted 14 lines · Stephan Mueller
Am Dienstag, 24. November 2015, 18:34:55 schrieb Herbert Xu:
Hi Herbert,
Quoted 10 lines · Dave Watson
Quoted 4 lines
Userspace crypto interface for TLS. Currently supports gcm(aes) 128bit only, however the interface is the same as the rest of the
SOCK_ALGinterface, so it should be possible to add more without any user interface changes.
SOCK_ALGexists to export crypto algorithms to user-space. So if we decided to support TLS as an algorithm then I guess this makes sense.
Quoted 7 lines
Quoted 3 lines
However, I must say that it wouldn't have been my first pick. I'd imagine a TLS socket to look more like a TCP socket, or perhaps a KCM socket as proposed by Tom.
If I may ask: what is the benefit of having TLS in kernel space? I do not see any reason why higher-level protocols should be in the kernel as they do not relate to accessing hardware.
There are some crypto acclerators out there so that putting tls into the kernel would give a net benefit, because otherwise user space has to copy data into the kernel for device access and back to user space until it can finally be send out on the wire.
Since processors provide aesni and other crypto extensions as part of their instruction set architecture, this, of course, does not make sense any more.
Quoted 8 lines
The only reason I could fathom is to keep the negotiated keys in a secure realm. But that could be done without having parts or the whole TLS protocol stack in the kernel. If the key management should stay in the kernel as a protection domain, I would rather think that the kernel should offer a plug- and-play of raw ciphers where user space is responsible to form a protocol. This way, we do not limit such key management to TLS, but allow any kind of protocol to use it.
Quoted 6 lines
E.g. the kernel performs the key transport with RSA or key agreement with DH using keyring-based key material. The resulting shared secret is again maintained in the key ring where user space can use the symmetric ciphers of the kernel with those keys. User space would only see references to keys but no real keys. However, only user space knows when to invoke what cipher to implement a specific protocol.
You could also keep the secret in a master process and talk to that via ipc.
Bye,
Hannes
Re: [RFC PATCH 2/2] Crypto kernel tls socket
Quoted 8 lines · Hannes Frederic Sowa
There are some crypto acclerators out there so that putting tls into the kernel would give a net benefit, because otherwise user space has to copy data into the kernel for device access and back to user space until it can finally be send out on the wire.
Since processors provide aesni and other crypto extensions as part of their instruction set architecture, this, of course, does not make sense any more.
BTW, that, exactly, was what happened to Solaris kssl.
--Sowmini
Re: [RFC PATCH 2/2] Crypto kernel tls socket
In reply to Hannes Frederic SowaHi,
Quoted 24 lines · Hannes Frederic Sowa
Quoted 14 lines · Stephan Mueller
Am Dienstag, 24. November 2015, 18:34:55 schrieb Herbert Xu:
Hi Herbert,
Quoted 10 lines · Dave Watson
Quoted 4 lines
Userspace crypto interface for TLS. Currently supports gcm(aes) 128bit only, however the interface is the same as the rest of the
SOCK_ALGinterface, so it should be possible to add more without any user interface changes.
SOCK_ALGexists to export crypto algorithms to user-space. So if we decided to support TLS as an algorithm then I guess this makes sense.Quoted 7 lines
Quoted 3 lines
However, I must say that it wouldn't have been my first pick. I'd imagine a TLS socket to look more like a TCP socket, or perhaps a KCM socket as proposed by Tom.
If I may ask: what is the benefit of having TLS in kernel space? I do not see any reason why higher-level protocols should be in the kernel as they do not relate to accessing hardware.
Quoted 8 lines
There are some crypto acclerators out there so that putting tls into the kernel would give a net benefit, because otherwise user space has to copy data into the kernel for device access and back to user space until it can finally be send out on the wire.
Since processors provide aesni and other crypto extensions as part of their instruction set architecture, this, of course, does not make sense any more.
There "still" are dedicated crypto engines out there which need a driver to be accessed, so using them from userspace is not as simple as with padlock or AESNI. This was the reasoning behind the various cryptodev implementations and af_alg. Using those to establish a TLS connection with OpenSSL means to fetch encrypted data to userspace first and then feed it to the kernel again for decryption. Using cryptodev-linux, this will be zero-copy, but still there's an additional context switch involved which the approach here avoids.
Cheers, Phil
Re: [RFC PATCH 2/2] Crypto kernel tls socket
Am Dienstag, 24. November 2015, 12:54:07 schrieb Phil Sutter:
Hi Phil,
Quoted 9 lines
There "still" are dedicated crypto engines out there which need a driver to be accessed, so using them from userspace is not as simple as with padlock or AESNI. This was the reasoning behind the various cryptodev implementations and
af_alg. Using those to establish a TLS connection with OpenSSL means to fetch encrypted data to userspace first and then feed it to the kernel again for decryption. Using cryptodev-linux, this will be zero-copy, but still there's an additional context switch involved which the approach here avoids.
Well, when being nasty, I could ask, why not putting the entire web server into the kernel. Heck, why not getting rid of user space?
Sorry, I could not resist. :-)
But back to the technical discussion. My main concern is that TLS is a big protocol and it is by far not the only crypto protocol where all those protocols seem to uses the same crypto primitives. And to me, there should be a good reason why software executes in supervisor state. Simply saving some context switches is not a good argument, because the context switches are there for a reason: to keep the system safe and secure.
Ciao
Stephan
Re: [RFC PATCH 2/2] Crypto kernel tls socket
In reply to Hannes Frederic SowaAm Dienstag, 24. November 2015, 12:20:00 schrieb Hannes Frederic Sowa:
Hi Hannes,
Quoted 3 lines
You could also keep the secret in a master process and talk to that via ipc.
I could not agree more.
Ciao
Stephan
Hello,
Quoted 23 lines · Dave Watson
An approach for a kernel TLS socket.
Only the symmetric encryption / decryption is done in-kernel, as well as minimal framing handling. The handshake is kept in userspace, and the negotiated cipher / keys / IVs are then set on the
algif_tlssocket, which is then hooked in to a tcp socket using sk_write_space/sk_data_ready hooks.If a non application-data TLS record is seen, it is left on the TCP socket and an error is returned on the ALG socket, and the record is left for userspace to manage. Userspace can't ignore the message, but could just close the socket.
TLS could potentially also be done directly on the TCP socket, but seemed a bit harder to work with the OOB data for non
application_datamessages, and the sockopts / CMSGS already exist for ALG sockets. The flip side is having to manage two fds in userspace.Some reasons we're looking at this:
1) Access to sendfile/splice for CDN-type applications. We were inspired by Netflix exploring this in FreeBSD
Quoted 7 lines
https://people.freebsd.org/~rrs/asiabsd_2015_tls.pdf
For perf, this patch is almost on par with userspace OpenSSL. Currently there are some copies and allocs to support scatter/gather in
aesni-intel_glue.c, but with some extra work to remove those (not included here), asendfile()is faster than the equivalent userspace read/SSL_write using a 128k buffer by 2~7%.
This argument is mood:
We already have mmap+vmsplice working on TCP sockets and ERR_MSGQUEUE notifications are already send when to advance the window. Please provide a benchmark using those already existing facilities.
I am pretty sure you at least need one data copy (as stated in the referred paper). Linux kernel can do this in user space already. FreeBSD only implements sendfile, thus this was the easier way for them to go.
Quoted 8 lines
2) Access to the unencrypted bytes in kernelspace. For example, Tom Herbert's kcm would need this
https://lwn.net/Articles/657999/3) NIC offload. To support running aesni routines on the NIC instead of the processor, we would probably need enough of the framing interface put in kernel.
This would require adding TOE offloading. The kernel community was a strong opponent to TOE offloading.
Bye,
Hannes
Quoted 19 lines · Dave Watson
An approach for a kernel TLS socket.
Only the symmetric encryption / decryption is done in-kernel, as well as minimal framing handling. The handshake is kept in userspace, and the negotiated cipher / keys / IVs are then set on thealgif_tlssocket, which is then hooked in to a tcp socket using sk_write_space/sk_data_ready hooks.
If a non application-data TLS record is seen, it is left on the TCP socket and an error is returned on the ALG socket, and the record is left for userspace to manage. Userspace can't ignore the message, but could just close the socket.
TLS could potentially also be done directly on the TCP socket, but seemed a bit harder to work with the OOB data for nonapplication_datamessages, and the sockopts / CMSGS already exist for ALG sockets. The flip side is having to manage two fds in userspace.
Some reasons we're looking at this:1) Access to sendfile/splice for CDN-type applications. We were inspired by Netflix exploring this in FreeBSD
Quoted 7 lines
https://people.freebsd.org/~rrs/asiabsd_2015_tls.pdf
For perf, this patch is almost on par with userspace OpenSSL. Currently there are some copies and allocs to support scatter/gather in
aesni-intel_glue.c, but with some extra work to remove those (not included here), asendfile()is faster than the equivalent userspace read/SSL_write using a 128k buffer by 2~7%.
Hi,
That's quite an interesting feature as we were investigating
something similar for openconnect VPN. One additional argument for such functionality is the acceleration of SSL VPNs. With a TLS (or DTLS) socket one could avoid expensive copies from tun to userspace and then to network layer and vice versa. The tricky part would be how easy one could switch from the kernel TLS implementation to userspace TLS implementation (e.g., to perform a rehandshake) and vice versa.
regards,
Nikos