From mboxrd@z Thu Jan 1 00:00:00 1970 From: Dave Watson Subject: Re: Security enhancement proposal for kernel TLS Date: Mon, 30 Jul 2018 14:16:11 -0700 Message-ID: <20180730211611.GA48199@glawler-mbp.dhcp.thefacebook.com> References: <20180725155946.GA37315@davejwatson-mba.local> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Cc: "netdev@vger.kernel.org" , Peter Doliwa , Boris Pismenny To: Vakul Garg Return-path: Received: from mx0a-00082601.pphosted.com ([67.231.145.42]:43758 "EHLO mx0a-00082601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731165AbeG3WxW (ORCPT ); Mon, 30 Jul 2018 18:53:22 -0400 Content-Disposition: inline In-Reply-To: Sender: netdev-owner@vger.kernel.org List-ID: 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. 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.