<div dir="ltr"><div><span style="font-size:12.8px">Hi, Matt</span></div><div><span style="font-size:12.8px"><sorry I  repied this mail and copied replies from daily digest></span></div><div><span style="font-size:12.8px">Thanks for your quickly response. </span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">And yes, with this option </span><span style="font-size:12.8px">SSL_OP_DONT_INSERT_EMPTY_</span><wbr style="font-size:12.8px"><span style="font-size:12.8px">FRAGMENTS in client side  the result can be get from one decryption. But the problem is, sometimes we can't control client's behavior.  Maybe the client is openssl s_client, or maybe it's a python script or some other client, and the option is not that safe.</span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">Another interesting thing is,  if server is using OpenSSL 1.0.2 or1.0.1, the result can be get from just one decryption(one tls1_enc method) with protocol TLSv1, and the client didn't add that option either(In fact, I'm using client OpenSSL1.1.0f). So it seems the process is changed in some version of OpenSSL1.1.0.  </span></div><div><span style="font-size:12.8px">Could you please explain a bit more on why openSSL 1.1.0f made this change? (I mean, the </span><span style="font-size:12.8px">SSL_OP_DONT_INSERT_EMPTY_</span><wbr style="font-size:12.8px"><span style="font-size:12.8px">FRAGMENTS option is added since 0.9.6d but openSSL1.0.1 and 1.0.2 can get result in one tls1_enc, while OpenSSL1.1.0f needs two tls1_enc</span><span style="font-size:12.8px">)</span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">The reason why I'm focus on this is because:  I'm using JNI call OpenSSL, my usage is like this(Just like tomcat native ):  first, use BIO_write to write data to openssl, and then use SSL_read to read 0 length to trigger decryption, and then use SSL_pending to check how much data there is. If the data length is not put in result buffer in one decryption. then SSL_pending will get a 0 length result. and the whole process needs to be changed ,which is not we want.</span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">Thanks.</span></div><div><span style="font-size:12.8px"><br></span></div><span style="font-size:12.8px"><div><span style="font-size:12.8px"><br></span></div>>From: Matt Caswell <</span><a href="mailto:matt@openssl.org" style="font-size:12.8px">matt@openssl.org</a><span style="font-size:12.8px">></span><br style="font-size:12.8px"><span style="font-size:12.8px">>To: </span><a href="mailto:openssl-dev@openssl.org" style="font-size:12.8px">openssl-dev@openssl.org</a><br style="font-size:12.8px"><span style="font-size:12.8px">>Subject: Re: [openssl-dev] why TLSv1 need two tls1_enc to get</span><br style="font-size:12.8px"><span style="font-size:12.8px">>        decrypted data while TLSv1.1/TLSv1.2 need one in OpenSSL1.1.0f?</span><br style="font-size:12.8px"><span style="font-size:12.8px">>Message-ID: <</span><a href="mailto:0890716d-2a3c-a659-f74e-7f2a5a89eca6@openssl.org" style="font-size:12.8px">0890716d-2a3c-a659-f74e-<wbr>7f2a5a89eca6@openssl.org</a><span style="font-size:12.8px">></span><br style="font-size:12.8px"><span style="font-size:12.8px">>Content-Type: text/plain; charset=utf-8</span><br style="font-size:12.8px">><br style="font-size:12.8px">><br style="font-size:12.8px">><br style="font-size:12.8px"><span style="font-size:12.8px">>On 27/09/17 15:44, Ma chunhui wrote:</span><br style="font-size:12.8px"><span style="font-size:12.8px">>> Hi,?</span><br style="font-size:12.8px"><span style="font-size:12.8px">>></span><br style="font-size:12.8px"><span style="font-size:12.8px">>> I met one problem when using OpenSSL1.1.0f with protocol TLSv1.</span><br style="font-size:12.8px"><span style="font-size:12.8px">>> In brief, when using TLSv1, ?after server side received encrypted data,</span><br style="font-size:12.8px"><span style="font-size:12.8px">>> and after function tls1_enc finished, the decrypted data is not put in</span><br style="font-size:12.8px"><span style="font-size:12.8px">>> result buffer, after another tls1_enc, the decrypted data is put in</span><br style="font-size:12.8px"><span style="font-size:12.8px">>> result buffer. While TLSv1.1/TLSv1.2 needs only one tls1_enc.</span><br style="font-size:12.8px"><span style="font-size:12.8px">>></span><br style="font-size:12.8px"><span style="font-size:12.8px">>></span><br style="font-size:12.8px"><span style="font-size:12.8px">>> The way to reproduce it is quite simple:</span><br style="font-size:12.8px"><span style="font-size:12.8px">>></span><br style="font-size:12.8px"><span style="font-size:12.8px">>> 1.some preparation: openssl req -x509 -newkey rsa:2048 -keyout key.pem</span><br style="font-size:12.8px"><span style="font-size:12.8px">>> -out cert.pem -days 365 -nodes</span><br style="font-size:12.8px"><span style="font-size:12.8px">>> 2.start server: openssl s_server -key key.pem -cert cert.pem -accept</span><br style="font-size:12.8px"><span style="font-size:12.8px">>> 44330 -www</span><br style="font-size:12.8px"><span style="font-size:12.8px">>> ? ? it's better to start server with gdb, and set breakpoints at</span><br style="font-size:12.8px"><span style="font-size:12.8px">>> tls1_enc, then continue to run.?</span><br style="font-size:12.8px"><span style="font-size:12.8px">>> 3.openssl s_client -connect localhost:44330 -tls1 -debug</span><br style="font-size:12.8px"><span style="font-size:12.8px">>></span><br style="font-size:12.8px"><span style="font-size:12.8px">>> After the client is started, ?the server side will stop at breakpoint,</span><br style="font-size:12.8px"><span style="font-size:12.8px">>> do several "c" to make it continue to run to wait for client's messages</span><br style="font-size:12.8px"><span style="font-size:12.8px">>> Then at client side, type a simple "hello" message and press Enter. Then</span><br style="font-size:12.8px"><span style="font-size:12.8px">>> server side will stop at tls1_enc, the input data is same as encrypted</span><br style="font-size:12.8px"><span style="font-size:12.8px">>> data from client side, but after Evp_Cipher and some pad removing, the</span><br style="font-size:12.8px"><span style="font-size:12.8px">>> decrypted data length is 0. After another tls1_enc, the decrypted data</span><br style="font-size:12.8px"><span style="font-size:12.8px">>> "hello" is put in the result buffer.</span><br style="font-size:12.8px"><span style="font-size:12.8px">>></span><br style="font-size:12.8px"><span style="font-size:12.8px">>> But if client use -tls11 or -tls12, the decrypted "hello" is put in the</span><br style="font-size:12.8px"><span style="font-size:12.8px">>> result buffer after the first tls1_enc.</span><br style="font-size:12.8px"><span style="font-size:12.8px">>></span><br style="font-size:12.8px"><span style="font-size:12.8px">>> Could anyone explains why the behavior of decryption is different</span><br style="font-size:12.8px"><span style="font-size:12.8px">>> between TLSv1 and TLSv1.1/TLSv1.2?</span><br style="font-size:12.8px">><br style="font-size:12.8px"><span style="font-size:12.8px">>In TLSv1 and below the CBC IV is the previous record's last ciphertext</span><br style="font-size:12.8px"><span style="font-size:12.8px">>block. This can enable certain types of attack where an attacker knows</span><br style="font-size:12.8px"><span style="font-size:12.8px">>the IV that will be used for a record in advance. The problem was fixed</span><br style="font-size:12.8px"><span style="font-size:12.8px">>in the specification of TLSv1.1 and above where a new IV is used for</span><br style="font-size:12.8px"><span style="font-size:12.8px">>each record. As a counter measure to this issue OpenSSL (in TLSv1) sends</span><br style="font-size:12.8px"><span style="font-size:12.8px">>an empty record before each "real" application data record to</span><br style="font-size:12.8px"><span style="font-size:12.8px">>effectively randomise the IV and make it unpredictable so that an</span><br style="font-size:12.8px"><span style="font-size:12.8px">>attacker cannot know it in advance.</span><br style="font-size:12.8px">><br style="font-size:12.8px"><span style="font-size:12.8px">>Therefore a TLSv1 OpenSSL client will send two records of application</span><br style="font-size:12.8px"><span style="font-size:12.8px">>data where a TLSv1.1 or above OpenSSL client will just send one. This</span><br style="font-size:12.8px"><span style="font-size:12.8px">>results in tls1_enc being called twice on the server side.</span><br style="font-size:12.8px">><br style="font-size:12.8px"><span style="font-size:12.8px">>This behaviour can be switched off by using the option</span><br style="font-size:12.8px"><span style="font-size:12.8px">>SSL_OP_DONT_INSERT_EMPTY_</span><wbr style="font-size:12.8px"><span style="font-size:12.8px">FRAGMENTS - but since this is considered</span><br style="font-size:12.8px"><span style="font-size:12.8px">>insecure that would probably be unwise.</span><br style="font-size:12.8px">><br style="font-size:12.8px"><span style="font-size:12.8px">>Matt</span><br style="font-size:12.8px"><br style="font-size:12.8px"></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Sep 27, 2017 at 10:44 PM, Ma chunhui <span dir="ltr"><<a href="mailto:mch.thu@gmail.com" target="_blank">mch.thu@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi, <div><br></div><div>I met one problem when using OpenSSL1.1.0f with protocol TLSv1.</div><div>In brief, when using TLSv1,  after server side received encrypted data, and after function tls1_enc finished, the decrypted data is not put in result buffer, after another tls1_enc, the decrypted data is put in result buffer. While TLSv1.1/TLSv1.2 needs only one tls1_enc.</div><div><br></div><div><br></div><div>The way to reproduce it is quite simple:<br></div><div><div style="font-size:12.8px"><div><br></div><div>1.some preparation: openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes</div><div>2.start server: openssl s_server -key key.pem -cert cert.pem -accept 44330 -www</div><div>    it's better to start server with gdb, and set breakpoints at tls1_enc, then continue to run. </div><div>3.openssl s_client -connect localhost:44330 -tls1 -debug</div></div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">After the client is started,  the server side will stop at breakpoint, do several "c" to make it continue to run to wait for client's messages</div><div style="font-size:12.8px">Then at client side, type a simple "hello" message and press Enter. Then server side will stop at tls1_enc, the input data is same as encrypted data from client side, but after Evp_Cipher and some pad removing, the decrypted data length is 0. After another tls1_enc, the decrypted data "hello" is put in the result buffer.</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">But if client use -tls11 or -tls12, the decrypted "hello" is put in the result buffer after the first tls1_enc.</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">Could anyone explains why the behavior of decryption is different between TLSv1 and TLSv1.1/TLSv1.2?</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">Thanks.</div></div></div>
</blockquote></div><br></div>