hakasenyang / openssl-patch

OpenSSL & NginX Patch
https://hks.pw/ossl
Other
194 stars 27 forks source link

Enable CHACHA20-Draft Version in Openssl 1.1.0 and later #1

Closed Jemmy1228 closed 6 years ago

Jemmy1228 commented 6 years ago

The Cloudflare patch can enable Both CHACHA20-RFC(0xcca8-0xccaa) ciphers and CHACH20-Draft(0xcc13-0xcc15) ciphers in Openssl 1.0.2f-j I tried to make the Cloudflare patch compatible with Openssl-1.1.1-pre9 by myself, by adding the CHACHA-Draft back to it, but I met a lot of difficulties and caused many errors. Can you please make such a patch that enable both the RFC and Draft CHACHA20 ciphers in Openssl 1.1.0 I think it would be very useful for everyone

hakasenyang commented 6 years ago

I think it's useful, but the draft version is obsolete. As of 1.1.0, chacha20 supports the rfc version, not the draft version.

1.0.2 and 1.1.1 have a lot of differences, which makes it difficult to patch.

I will try, but I do not know if it is possible.

P.S. Google(google.com, etc.) has already removed OLD CHACHA from SSL Cipher.

Sorry my poor english.

Jemmy1228 commented 6 years ago

Though draft version ciphers are obsolete, they are still secure. As far as I know, Cloudflare is still using Draft version ciphers to perform handshake with Android 6 devices. No matter is it possible or not, thank you very much. And I've learnt a lot from your patches. p.s. I'm not a English speaker as well! :)

hamjin commented 6 years ago

Also, old device with old Android(like 5.0 and 6.0) can only use chacha20-draft

hakasenyang commented 6 years ago

I tried to support the CHACHA draft and the CHACHA draft handshake succeeded, but subsequent encryption and decryption failed.

It's too hard. :(

image

It is recommended to use AES because AES also guarantees sufficient safety... :-)

hamjin commented 6 years ago

You can see boringssl branch 2987 (git clone -b 2987 https://github.com/google/boringssl )and clousflare's patch(https://github.com/cloudflare/sslconfig/ )

hamjin commented 6 years ago

But you need to know that cloudflare's patc use AVX/AVX2 and SSE4 that could not work on some server(like Raspberry Pi, old Intel/AMD Proccers and ALL OF ARM DEVICES) EDIT:Now I tested the pure C code in the patch and it is ok for all devices with a super fast speed

hakasenyang commented 6 years ago

I have searched for related materials, but for me, assembly is too difficult.

I am currently consulting documentation on encryption and decryption after handshaking.

hamjin commented 6 years ago

Thank you!

hamjin commented 6 years ago

Encryption and decryption after handshaking is more difficult than handshake... You can read the code in BoringSSL branch 2987, it's a good example that it has both RFC version and Draft version.

Jemmy1228 commented 6 years ago

The documentation of Chacha-Draft is here https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04

And the documentation of ChaCha-RFC version is here https://tools.ietf.org/html/rfc7905

There isn't much difference between these two I think... I've found a page that tells the differences here https://blog.cloudflare.com/it-takes-two-to-chacha-poly/

I tried to rewrite the code with these documentations, but I can't even compile it successfully!

hamjin commented 6 years ago

The draft version is for old servers which have no SSE codes and AVX codes, that makes the code running almost all the devices

ymshenyu commented 6 years ago

maybe chrome or firefox on android 6 could use rfc chacha20 , and chrome support tls 1.3 draft28 now. @hakasenyang is that mean we dont need draft 23 anymore?

hamjin commented 6 years ago

@ymshenyu No, we need to make Internet safer and TLS1.3 draft23 26 28 is enough safe, so we needn't delete draft 23 support

ymshenyu commented 6 years ago

@railjty ok , actually draft 23 and 28 are draft standard so they are both safe i think , and android chrome still using draft 23 . android chrome did not release version 68 yet

hakasenyang commented 6 years ago

I tried to try it all the time, but it is very difficult. I'm sorry. I think it is probably hard to solve.

Jemmy1228 commented 6 years ago

That's all right...you needn't say sorry at all. It is really a difficult thing. I'm sorry that this issue maybe cost you a lot of time :( . Thank you anyway!

ymshenyu commented 6 years ago

tls 1.3 standard version came out https://www.rfc-editor.org/rfc/rfc8446.txt

ymshenyu commented 6 years ago

openssl 1.1.1 pre9 dev update code https://github.com/openssl/openssl/commit/35e742ecac9239539db016e1282b4cbdf501509c

hakasenyang commented 6 years ago

@ymshenyu Yes. I already responded to the patch.

https://github.com/hakasenyang/openssl-patch/blob/master/openssl-equal-pre9_ciphers.patch

Jemmy1228 commented 6 years ago

@hakasenyang I faced a problem with your new patch, but I don't want to start a new issue...
I upgraded my openssl and used your patch again, however this time my server cannot even establish tls1.3 handshake?
openssl s_client -connect localhost:443 -servername breakwall.ml -tls1_3
this is the command I used to try tls1.3 handshake, however openssl responded

CONNECTED(00000005)
140621557682624:error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version:ssl/record/rec_layer_s3.c:1528:SSL alert number 70
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 249 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---

And nginx logged 2018/08/18 09:28:37 [crit] 22523#22523: *3 SSL_do_handshake() failed (SSL: error:14209102:SSL routines:tls_early_post_process_client_hello:unsupported protocol) while SSL handshaking,

I tried the newest version and the exact version of openssl you said which is compatible (https://github.com/openssl/openssl/tree/2805ee1e095a78f596dc7adf778441e2edb9f15c) Neither with or without "_ciphers" patch support any version of tls1.3

I wonder why... (If you want to connect to my server, you have to use SNI...)

And if I don't use any patch, s_client still cannnot establish tls1.3 handshake
I have no idea that can original nginx and original openssl support tls1.3 if I don't use any patch?

hakasenyang commented 6 years ago

Hello, @JemmyLoveJenny

 SSLv2      not offered (OK)
 SSLv3      not offered (OK)
 TLS 1      offered
 TLS 1.1    offered
 TLS 1.2    offered (OK)
 TLS 1.3    not offered
 NPN/SPDY   h2, spdy/3.1, http/1.1 (advertised)
 ALPN/HTTP2 h2, spdy/3.1, http/1.1 (offered)

Your server has not been enabled for TLS 1.3. Please check your nginx settings and the openssl version again.

Use nginx -V

Example)

# nginx -V
nginx version: nginx/1.15.3
built by gcc 8.1.0 (GCC)
built with OpenSSL 1.1.1-pre9-dev  xx XXX xxxx
TLS SNI support enabled
ymshenyu commented 6 years ago

BoringSSL with Nginx trunk can use 0-rtt now . but i dont like BoringSSL because it didnt support ocsp stapling by default . and i dont want to use it patch to turn it on .

Jemmy1228 commented 6 years ago

@hakasenyang I'm sure that I enabled TLS1.3

        # SSL Settings
        ##
        #
        #Protocols
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
        #
        #Key Exchange
        ssl_ecdh_curve X25519:P-256:P-384:P-224:P-521;
        ssl_dhparam /var/SSL/DH-param.pem;
        #
        #Cipher Suites
        ssl_ciphers "[TLS_AES_128_GCM_SHA256|TLS_CHACHA20_POLY1305_SHA256]:[TLS_AES_256_GCM_SHA384|TLS_AES_128_CCM_8_SHA256|TLS_AES_128_CCM_SHA256]:[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256|DHE-RSA-CHACHA20-POLY1305]:[ECDHE-ECDSA-AES256-GCM-SHA384|ECDHE-RSA-AES256-GCM-SHA384]:[ECDHE-ECDSA-AES128-SHA|ECDHE-RSA-AES128-SHA]:[ECDHE-ECDSA-AES256-SHA|ECDHE-RSA-AES256-SHA]:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA";
        ssl_prefer_server_ciphers on;
        #

and my nginx

nginx version: nginx/1.15.0
built by gcc 7.3.0 (Ubuntu 7.3.0-16ubuntu3)
built with OpenSSL 1.1.1-pre9-dev  xx XXX xxxx
TLS SNI support enabled

and I set some options of openssl when compiling nginx

--with-openssl=../openssl \
--with-openssl-opt='enable-weak-ssl-ciphers no-comp enable-egd threads' \
ymshenyu commented 6 years ago

@JemmyLoveJenny maybe nginx version ? my server still use pre8 . i am not sure

Jemmy1228 commented 6 years ago

@ymshenyu my configuration works well when I was using openssl-pre9 with tls1.3 28

ymshenyu commented 6 years ago

@JemmyLoveJenny well , reconfigure openssl without patch ?

Jemmy1228 commented 6 years ago

@ymshenyu I tried reconfigure without patch, but still can't establish tls1.3 handshake. But I don't think original openssl with nginx support tls 1.3

hakasenyang commented 6 years ago

@JemmyLoveJenny Could you test the openssl build with this version? https://git.hakase.app/Hakase/openssl-custom

Jemmy1228 commented 6 years ago

@hakasenyang Wait a minute, I will try...

ymshenyu commented 6 years ago

@JemmyLoveJenny and without --with-openssl-opt=

ymshenyu commented 6 years ago

nginx version: nginx/1.14.0 built by gcc 7.3.0 (Ubuntu 7.3.0-16ubuntu3) built with OpenSSL 1.1.1-pre8 (beta) 20 Jun 2018 TLS SNI support enabled configure arguments: --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module --with-http_sub_module --with-http_xslt_module --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-threads --with-openssl=/usr/local/tls13 --add-module=../ngx_brotli --add-module=../incubator-pagespeed-ngx-1.13.35.2-stable

this is my options

hamjin commented 6 years ago

You can update your openssl to the master branch, and then use the patch.@ymshenyu

ymshenyu commented 6 years ago

@railjty i will try that on my oracle virtualbox

hamjin commented 6 years ago

@JemmyLoveJenny You can only left the weak ssl ciphers option in your openssl opt, and then test the patch

hamjin commented 6 years ago

Note that although OpenSSL supports 0-RTT, but NGINX does not use it with openssl but boringssl

hakasenyang commented 6 years ago

@JemmyLoveJenny Okay. I found a solution through experiments.

TLSv1.3 must be enabled where SNI is not included. That is, activate ssl_protocols TLSv1.3 where the first server { (443 port) starts. example)

     server {
         listen 443 ssl http2 default_server;
         server_name localhost;
         ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
         ...
     }

Or Change nginx source as follows: src/http/modules/ngx_http_ssl_module.c:

    ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
                         (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1
                          |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));

to

    ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
                         (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1
                          |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2|NGX_SSL_TLSv1_3));

and then, clear all ssl_protocols from your nginx configuration.

Jemmy1228 commented 6 years ago

@hakasenyang I compiled but still failed to perform tls1.3 handshake

Jemmy1228 commented 6 years ago

@hakasenyang Wow! I didn't see you recent comment just now! I wonder why? I intended to enable strict sni ...

hamjin commented 6 years ago

I add the SSL options to the global nginx config(nginx.conf http{}), it works well

Jemmy1228 commented 6 years ago

I would try again...

kn007 commented 6 years ago
nginx version: kn007's Server/1.15.2
built by gcc 7.3.1 20180303 (Red Hat 7.3.1-5) (GCC)
built with OpenSSL 1.1.1-pre9-dev  xx XXX xxxx
TLS SNI support enabled

 SSLv2      not offered (OK)
 SSLv3      not offered (OK)
 TLS 1      offered
 TLS 1.1    offered
 TLS 1.2    offered (OK)
 TLS 1.3    offered (OK): draft 28, draft 26, draft 23, final
 NPN/SPDY   h2, spdy/3.1, http/1.1 (advertised)
 ALPN/HTTP2 h2, spdy/3.1, http/1.1 (offered)

The latest patch working fine for me

hamjin commented 6 years ago

So we only add 'ssl_protocol TLSv1 TLSv1.1 TLSv1.2 TLSv1.3,' in nginx.conf http block

Jemmy1228 commented 6 years ago

@hakasenyang I disabled strict SNI and it worked!

hakasenyang commented 6 years ago

@JemmyLoveJenny nginx's ssl_module recognizes the "beginning" ssl_protocols (not sni) and starts handshake to the opponent. Therefore, TLSv1.3 must be enabled for all settings, regardless of SNI.

hamjin commented 6 years ago

@hakasenyang You are right!

hamjin commented 6 years ago

@JemmyLoveJenny Enable TLS1.3 in all server block, and it may work

Jemmy1228 commented 6 years ago

@hakasenyang But that's a bit strange ... why the former version of openssl works fine with nginx? I had been enabling strict sni for a long time

ymshenyu commented 6 years ago

i am out , this is too strange . XD

Jemmy1228 commented 6 years ago

@railjty Yes, I enabled TLS1.3 for all hosts.(set in the nginx.conf) But still fails

hakasenyang commented 6 years ago

@JemmyLoveJenny I don't know what Strict SNI means.