Thread (8 messages) 8 messages, 2 authors, 2018-08-03

Re: Security enhancement proposal for kernel TLS

From: Dave Watson <hidden>
Date: 2018-07-30 22:53:22

On 07/30/18 06:31 AM, Vakul Garg wrote:
quoted
It's not entirely clear how your TLS handshake daemon works -   Why is
it necessary to set the keys in the kernel tls socket before the handshake is
completed? 
IIUC, with the upstream implementation of tls record layer in kernel, the
decryption of tls FINISHED message happens in kernel. Therefore the keys are
already being sent to kernel tls socket before handshake is completed.
This is incorrect.  Currently the kernel TLS implementation decrypts
everything after you set the keys on the socket.  I'm suggesting that
you don't set the keys on the socket until after the FINISHED message.
quoted
Or, why do you need to hand off the fd to the client program
before the handshake is completed?
  
The fd is always owned by the client program..

In my proposal, the applications poll their own tcp socket using read/recvmsg etc.
If they get handshake record, they forward it to the entity running handshake agent.
The handshake agent could be a linux daemon or could run on a separate security
processor like 'Secure element' or say arm trustzone etc. The applications
forward any handshake message it gets backs from handshake agent to the
connected tcp socket. Therefore, the  applications act as a forwarder of the handshake 
messages between the peer tls endpoint and handshake agent.
The received data messages are absorbed by the applications themselves (bypassing ssl stack
completely). Similarly, the applications tx data directly by writing on their socket.
quoted
Waiting until after handshake solves both of these issues.
 
The security sensitive check which is 'Wait for handshake to finish completely before 
accepting data' should not be the onus of the application. We have enough examples
in past where application programmers made mistakes in setting up tls correctly. The idea
is to isolate tls session setting up from the applications.
It's not clear to me what you gain by putting this 'handshake
finished' notification in the kernel instead of in the client's tls
library - you're already forwarding the handshake start notification
to the daemon, why can't the daemon notify them back in userspace that
the handshake is finished?   

If you did want to put the notification in the kernel, how would you
handle poll on the socket, since probably both the handshake daemon
and client might be polling the socket, but one for control messages
and one for data? 

The original kernel TLS RFC did split these to two separate sockets,
but we decided it was too complicated, and that's not how userspace
TLS clients function today.

Do you have an implementation of this?  There are a bunch of tricky
corner cases here, it might make more sense to have something concrete
to discuss.
Further, as per tls RFC it is ok to piggyback the data records after the finished handshake
message. This is called early data. But then it is the responsibility of applications to first
complete finished message processing before accepting the data records.

The proposal is to disallow application world seeing data records
before handshake finishes.
You're talking about the TLS 1.3 0-RTT feature, which is indeed an
interesting case.  For in-process TLS libraries, it's fairly easy to
punt, and don't set the kernel TLS keys until after the 0-RTT data +
handshake message.  For an OOB handshake daemon it might indeed make
more sense to leave the data in kernelspace ... somehow.
quoted
quoted
	- The handshake state should fallback to 'unverified' in case a control
record is seen again by kernel TLS (e.g. in case of renegotiation, post
handshake client auth etc).

Currently kernel tls sockets return an error unless you explicitly handle the
control record for exactly this reason.
IIRC, any kind handshake message post handshake-completion is a problem for kernel tls.
This includes renegotiation, post handshake client-auth etc.

Please correct me if I am wrong.
You are correct, but currently kernel TLS sockets return an error
unless you explicitly handle the control message.  This should be
enough already to implement your proposal. 
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help