> -----Original Message-----
> From: Dave Watson [mailto:davejwat...@fb.com]
> Sent: Tuesday, July 31, 2018 2:46 AM
> To: Vakul Garg <vakul.g...@nxp.com>
> Cc: netdev@vger.kernel.org; Peter Doliwa <peter.dol...@nxp.com>; Boris
> Pismenny <bor...@mellanox.com>
> Subject: Re: Security enhancement proposal for kernel TLS
> 
> On 07/30/18 06:31 AM, Vakul Garg wrote:
> > > 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.  

Let us first reach a common ground on this.

 The kernel TLS implementation can decrypt only after setting the keys on the 
socket.
The TLS message 'finished' (which is encrypted) is received after receiving 
'CCS'
message. After the user space  TLS library receives CCS message, it sets the 
keys
on kernel TLS socket. Therefore, the next message in the  socket receive queue
which is TLS finished gets decrypted in kernel only.

Please refer to following Boris's patch on openssl. The  commit log says:
" We choose to set this option at the earliest - just after CCS is complete".

------------------------------------------------------
commit a01dd062a32c687630b2a860b4bb053008f09ff5
Author: Boris Pismenny <bor...@mellanox.com>
Date:   Sun Mar 11 16:18:27 2018 +0200

    ssl: Linux TLS Rx Offload
    
    This patch adds support for the Linux TLS Rx socket option.
    It completes the previous patch for TLS Tx offload.
    If the socket option is successful, then the receive data-path of the TCP
    socket is implemented by the kernel.
    We choose to set this option at the earliest - just after CCS is complete.
------------------------------------------------------

The  fact that keys are handed over to kernel TLS socket can also be verified
by putting a log in tls_sw_recvmsg().

I would stop here for you to confirm my observation first. 
Regards. Vakul


 > 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.
> 
> > > 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.
> >
> > > 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.
> 
> > > >         - 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.

Reply via email to