Comments (40)
Hello,
You could simply use AF_KTLS sockets (without the need for TLSe). However, it is a good idea to add tlse_sendfile and tlse_receivefile to avoid an additional memory allocation. With tlse_sendfile and tlse_receivefile you could simply use them on platforms without AF_KTLS. Would that be of any help for you?
from tlse.
Greetings,
No, you can't. AF_KTLS requires that userspace deals with the handshake, so you still need most of an SSL library.
I doubt it'd be too hard to add, but I'll admit I'm not sure about the details. And from what I can see, it wasn't merged upstream, so it may be hard to test.
from tlse.
kTLS was merged upstream in Linux 4.13. As far as I know, it's basically a replacement for the TLS record layer and nothing else (and I think it might be send-only for now), with the additional constraint that it only supports AES-128-GCM.
from tlse.
Ok, let me make a simple kTLS client and check it. If it implements only the TLS record layer (AES and GCM), I guess I could add support to TLSe. Also, a flag (something like TLS_WITH_KTLS) in order to advertise only (RSA)DHE/ECDHE + AES-128-GCM. It should be simple, but the problem is that is not portable. A simple kTLS example would be nice (a simple google search doesn't show much), so if you have one (server or client) it would be great :).
from tlse.
Ah, yes, you're right, it's there. I searched the repo for AF_KTLS, but apparently they went with some other mechanism.
Good to know, I may want to mess with that at some point...
from tlse.
Thanks! Pretty straightforward API. I will add support after setting up a Linux 4.15 machine. I use this library mostly on FreeBSD, so cannot test it. I'm thinking to something like tlse_ktls(tls, int sockfd). If it supports ktls it will set the appropriate flags on the socket. If it doesn't support, then it simply returns -1.
from tlse.
I see there are commits coming into the git repository! \o/ I'll be happy to test once you have something working.
from tlse.
Ok, it is working (at least in client). You must define WITH_KTLS in order to work. Maybe you could help me with something: I'm not sure about the headers I should include. For testing, I've created tls.h containing the ktls structures and constants. I guess I should include tls.h from linux headers, but when I do that, I get tons of conflicting declarations (tested with Linux kernel 4.15).
from tlse.
I'll probably be testing on server, since that's my use-case.
Normally, you're not supposed to include kernel headers directly AFAIK; only glibc is supposed to do that. I don't honestly know what the right solution is in this case, where glibc hasn't caught up yet. I think maybe your solution of just copying the includes for now isn't so bad, but you'd probably get a more authoritative answer if you asked some kernel people.
from tlse.
It should work on server too. I've attached the tls.h file that I used.
tls.h.txt
Note: you must call tls_make_exportable before key exchange/negotiation in order to keep a copy of the key in the tls context object.
Also, I've added tls_unmake_ktls to handle control messages: Upon receipt of a non-data TLS message(a control message), the KTLS socket returns an error, and the message is instead left on the original TCP socket. The KTLS socket is automatically unattached. Transfer of control back to the original encrypted FD is done by calling getsockopt to receive the current sequence numbers, and inserting them in to the TLS library.
from tlse.
OK, so the idea is to normally recv() as usual, but once you get that specific error, you call tls_unmake_ktls(), tls_consume_stream(), and then tls_make_ktls() again?
from tlse.
Yes. In reality the only control message you will get is close notify, so in case of error, you could just close the connection. I think TLS renegotiation is not used in practice (I remember something about a vulnerability).
from tlse.
Also, use send as normal not recv. kTLS is send-only.
from tlse.
I didn't understand the last part. I need to do recv through the library as normal, but when do the control message errors come in? Can I get those on send(), and then I need to unmake + recv + consume + make?
from tlse.
Or maybe unmake + recv + consume + get_write_buffer + send + make.
from tlse.
Normally, you're not supposed to include kernel headers directly AFAIK
why not? that's why there is a user-space API...
TLS renegotiation is not used in practice
it's even removed from TLS 1.3
probably this could help?
https://blog.filippo.io/playing-with-kernel-tls-in-linux-4-13-and-go/
FiloSottile/go@dbed997
from tlse.
From what I understand kTLS can be used only for write operations(sendfile). So, you use tlse to receive data, and send
to send. When you want to use tlse again, you just call tls_unmake_ktls. In practice you won't need to switch back to tlse for sending data.
If you check https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/tls.h
You will see that only TLS_TX is defined (write operations). Maybe in a future linux version, a TLS_RX will available.
As a flow:
if (tls_make_ktls(contxt))
// canot switch to ktls
send(sockfd, message, message_size, 0);
recv(...buf,,,)
tls_consume(buf)
I will create a kTLS server example these days.
from tlse.
OK, so basically I don't really need to care about tls_unmake_ktls at all, really. I only intend to send() and sendfile() once the initial connection is up anyway.
from tlse.
I'm trying to force TLSe to only negotiate AES-128-GCM. So far, I've modified tls_cipher_supported() to only accept those four ciphers, and tls_build_hello() to only announce them (and no mitigated ciphers, ie., TLS_CIPHERS_SIZE(4,0), is that OK?). But wget and openssl s_client still negotiate ECDHE-RSA-AES256GCM-SHA384; is there some trick here?
from tlse.
You should edit tls_cipher_is_fs. TLSe first tries to choose a forward secrecy cipher, then, if none is available, it falls to any common cipher.
TLS_CIPHERS_SIZE is client-side only, so if you want to create a server supporting only GCM, is of no use and you should leave it as it is.
How this works: the TLS client exchanges the hello, saying "I'm supporting these ciphers: AES_GCM ..CHACHA etc". in preferred order. Then, the server chooses a cipher from that list. So, if you want to force AES128-GCM, just edit tls_cipher_is_fs and disable anything except gcm ciphers. If client doesn't support AES128-GCM mode, you could fallback to another cipher. I remember something about AES128-CBC being mandatory. I don't know if AES128-GCM is mandatory in TLS.
from tlse.
That makes sense. I seem to recall there's a way to force server preference order, though?
from tlse.
Only by editing the server. In TLSe case, modifying tls_cipher_is_fs and tls_cipher_supported. If the client supports A, B, C, D, E, F, G, the server will choose the "first best one". In TLSe, I check first for FS ciphers, and then for others. So, if the client has B, D and E as FS ciphers, the server will choose B. The client may reorder the ciphers, E B D, and the server will then choose E instead of B.
FS ciphers use ephemeral Diffie-Hellman key exchange (DHE, ECDHE).
from tlse.
kTLS appears to work for me now; I'm sending a pull request to prefer kTLS-capable ciphers.
I haven't done extensive testing yet, just the very basics.
from tlse.
I think it is not a good idea to favor aes128-gcm just beacause is supported by ktls. The current cipher preference order is based on forward secrecy and cipher strength.
from tlse.
Well, if so, kTLS will essentially never be used. For my part, I'll just be turning off all non-kTLS ciphers (I won't be making a separate sendfile()-less path for non-kTLS); would you consider that, without the option to prefer, a reasonable choice?
from tlse.
I've modified TLSe to prefer AES128-GCM FS ciphers when compiled with -DWITH_KTLS, very similar to your pull request. It is important to keep the library comply with the TLS standards, so returning NO_COMMON_CIPHER if no AES128-GCM cipher is available it is a bad idea. There are a lot of IoT devices that don't implement anything else but RSA/AES128/CBC. In your application, you should handle both sendfile and a fail-safe mechanism for clients that don't support AES128-GCM.
from tlse.
Well, OK, it won't matter much to me what the library does; tls_make_ktls() will just fail, and then I'll be closing the connection. :-) (My use-case doesn't involve IoT devices or anything similarly low-powered; just a fairly small range of browsers and video players.) It will be a bit harder to debug, that's all.
from tlse.
Keep in mind that from time to time, a weakness is found in one ore more ciphers in TLS. If at some point, a weakness is found in AES128-GCM, it may be disabled in browsers. I think you should support at least 2 ciphers. See for example, ROBOT, which exploits a problem in key padding, making key negotiation using RSA unsafe.
from tlse.
Can we close this one?
from tlse.
Yes, it appears to work stable for me now, after some testing. There may still be bugs lurking, but if so, they can simply be filed as bugs—I think this tracking item is done. Thanks!
from tlse.
Note, 4.17 just got TLS_RX as well :-) But it's less important for my case.
from tlse.
Cool! I will add support as soon as I manage to install a 4.17 kernel.
from tlse.
Ok, added, but I have no way to test it now. If you have the time and setup, you may try it. Just be sure to consume all the pending data before calling tlse_make_ktls (read all the pending data in TLSe).
from tlse.
Hm; after making the call, how do you know whether your socket is now in TX-only kTLS, RX/TX kTLS, or neither? (If you're running on e.g. 4.15.)
from tlse.
If TLS_RX is defined, then tls_make_ktls will first try to set TLS_RX. If it fails, it returns -1 (setsockopt). If TLS_RX is not defined, then it is send-only. When compiling TLSe, you should define TLS_RX if supported, or include some kernel header that defines TLS_RX. In your code, you should have something like:
int err = tls_make_ktls(...)
if (!err) {
#ifdef TLS_RX
// send/recv
#else
// send only
#endif
}
Anyway, I guess that soon we will see kernel 4.17 in all major Linux distributions, so this is only a temporary inconvenience. I could add a parameter to tls_make_ktls(..., int flags)
, where flags is O_RDWR, O_RDONLY or O_WRONLY.
from tlse.
I originally assumed there would be separate calls, but I guess it's OK just to try send/recv unconditionally. As you say, it's likely that there won't be too many distros shipping 4.13–4.16.
from tlse.
If it is compiled with TLS_RX, the call will fail if TLS_RX is not supported (the socket is left untouched). If compiled with TLS_RX and you're running on 4.16, then the call to tls_make_ktls will fail. It will not set the TLS_TX option.
from tlse.
I haven't forgotten about testing this, but neither 4.17-rc1 nor 4.17-rc2 boots on any hardware I have, so it will have to wait for a while. :-)
from tlse.
I've tested with 4.17-rc4 now, and it seems to work fine. Unfortunately, I still have to have a path with tls_read() (at the very beginning of the stream, right after the handshake), because I suppose there could still be encrypted data left in tlse's buffers when I switch to kTLS.
from tlse.
Great! Thanks! You could check with tls_pending
if you have any data in TLSe buffer before calling tls_read. If it is non-zero, you must call tls_read, else you just call recv.
from tlse.
Related Issues (20)
- certificate_verify() is not called when using a TSL 1.3 client HOT 1
- Connect (to wikipedia) with V13 succeeds, but cannot read data. V12 works HOT 4
- Failure to connect to SMTP server with STARTTLS HOT 1
- Failure to notice incorrect handshake on SSL_connect
- TLS 1.3 server incompatible with openssl
- LTC_ARGCHK 'b != NULL' HOT 3
- Support for latest libtomcrypt HOT 5
- SSL_read function strange behavior vs openssl's SSL_read HOT 1
- Merge into tomcrypt HOT 2
- what is "for semantic compatibility" means? HOT 1
- Examples expects testcert folder. HOT 1
- HTTPS Server wont respond when using ECDHE-RSA-AES256GCM-SHA384 cipher HOT 1
- Growtopia wont respond when using TLSe HOT 14
- Async sockets. HOT 5
- Tomcrypt version HOT 2
- Is its possible to make HTTPS Proxy using TLSe? HOT 3
- A website using Cloudflare is giving me 403 when using test client code, but works with Chrome, why? HOT 5
- TLSE fails to contact Cloudflare server, where curl works fine, I eliminated every cause I could think of HOT 8
- How do i set TLSe Client Cipher? HOT 2
- TLS 1.3: Early data
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tlse.