Git Product home page Git Product logo

Comments (40)

eduardsui avatar eduardsui commented on August 16, 2024

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.

Alcaro avatar Alcaro commented on August 16, 2024

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.

sesse avatar sesse commented on August 16, 2024

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.

eduardsui avatar eduardsui commented on August 16, 2024

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.

Alcaro avatar Alcaro commented on August 16, 2024

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.

eduardsui avatar eduardsui commented on August 16, 2024

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.

sesse avatar sesse commented on August 16, 2024

I see there are commits coming into the git repository! \o/ I'll be happy to test once you have something working.

from tlse.

eduardsui avatar eduardsui commented on August 16, 2024

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.

sesse avatar sesse commented on August 16, 2024

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.

eduardsui avatar eduardsui commented on August 16, 2024

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.

sesse avatar sesse commented on August 16, 2024

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.

eduardsui avatar eduardsui commented on August 16, 2024

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.

eduardsui avatar eduardsui commented on August 16, 2024

Also, use send as normal not recv. kTLS is send-only.

from tlse.

sesse avatar sesse commented on August 16, 2024

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.

sesse avatar sesse commented on August 16, 2024

Or maybe unmake + recv + consume + get_write_buffer + send + make.

from tlse.

sjaeckel avatar sjaeckel commented on August 16, 2024

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.

eduardsui avatar eduardsui commented on August 16, 2024

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.

sesse avatar sesse commented on August 16, 2024

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.

sesse avatar sesse commented on August 16, 2024

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.

eduardsui avatar eduardsui commented on August 16, 2024

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.

sesse avatar sesse commented on August 16, 2024

That makes sense. I seem to recall there's a way to force server preference order, though?

from tlse.

eduardsui avatar eduardsui commented on August 16, 2024

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.

sesse avatar sesse commented on August 16, 2024

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.

eduardsui avatar eduardsui commented on August 16, 2024

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.

sesse avatar sesse commented on August 16, 2024

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.

eduardsui avatar eduardsui commented on August 16, 2024

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.

sesse avatar sesse commented on August 16, 2024

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.

eduardsui avatar eduardsui commented on August 16, 2024

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.

eduardsui avatar eduardsui commented on August 16, 2024

Can we close this one?

from tlse.

sesse avatar sesse commented on August 16, 2024

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.

sesse avatar sesse commented on August 16, 2024

Note, 4.17 just got TLS_RX as well :-) But it's less important for my case.

from tlse.

eduardsui avatar eduardsui commented on August 16, 2024

Cool! I will add support as soon as I manage to install a 4.17 kernel.

from tlse.

eduardsui avatar eduardsui commented on August 16, 2024

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.

sesse avatar sesse commented on August 16, 2024

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.

eduardsui avatar eduardsui commented on August 16, 2024

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.

sesse avatar sesse commented on August 16, 2024

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.

eduardsui avatar eduardsui commented on August 16, 2024

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.

sesse avatar sesse commented on August 16, 2024

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.

sesse avatar sesse commented on August 16, 2024

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.

eduardsui avatar eduardsui commented on August 16, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.