diff --git a/README.md b/README.md
index c34ec31..783c890 100644
--- a/README.md
+++ b/README.md
@@ -47,7 +47,7 @@ Here is the basic patch content.
| :--- | :--- |
| openssl-equal-1.1.1.patch
openssl-equal-1.1.2-dev.patch | Support **final (TLS 1.3)**, TLS 1.3 cipher settings **_can not_** be changed on _nginx_. |
| openssl-equal-1.1.1_ciphers.patch
openssl-equal-1.1.2-dev_ciphers.patch | Support **final (TLS 1.3)**, TLS 1.3 cipher settings **_can_** be changed on _nginx_. |
-| openssl-ignore_log_strict-sni.patch | When using nginx_strict-sni.patch, nginx ignores the error in error.log. [View issue](https://github.com/hakasenyang/openssl-patch/issues/1#issuecomment-421594901) |
+| openssl-1.1.1-chacha_draft.patch | A draft version of chacha20-poly1305 is available. [View issue](https://github.com/hakasenyang/openssl-patch/issues/1#issuecomment-427554824) |
**The "_ciphers" patch file is a temporary change to the TLS 1.3 configuration.**
@@ -83,6 +83,19 @@ patch -p1 < ../openssl-patch/openssl-equal-1.1.2-dev_ciphers.patch
And then use --with-openssl in nginx or build after ./config.
+### OpenSSL CHACHA20-POLY1305-OLD Patch
+
+Thanks [@JemmyLoveJenny](https://github.com/JemmyLoveJenny)!
+
+[View issue](https://github.com/hakasenyang/openssl-patch/issues/1#issuecomment-427554824) / [Original Source](https://github.com/JemmyLoveJenny/ngx_ossl_patches/blob/master/ossl_enable_chacha20-poly1305-draft.patch)
+
+```
+git clone https://github.com/openssl/openssl.git
+git clone https://github.com/hakasenyang/openssl-patch.git
+cd openssl
+patch -p1 < ../openssl-patch/openssl-1.1.1-chacha_draft.patch
+```
+
### nginx HPACK Patch
Run it from the nginx directory.
diff --git a/openssl-1.1.1-chacha_draft.patch b/openssl-1.1.1-chacha_draft.patch
new file mode 100644
index 0000000..4fca532
--- /dev/null
+++ b/openssl-1.1.1-chacha_draft.patch
@@ -0,0 +1,517 @@
+Issue: https://github.com/hakasenyang/openssl-patch/issues/1#issuecomment-427554824
+
+Original source : https://github.com/JemmyLoveJenny/ngx_ossl_patches/blob/master/ossl_enable_chacha20-poly1305-draft.patch
+
+After using this patch, you can use it as is.
+If necessary, use it with "EECDH+CHACHA20-D".
+If you use EECDH+CHACHA20, the OLD version is also used at the same time.
+
+diff --git a/crypto/evp/c_allc.c b/crypto/evp/c_allc.c
+index 086b3c4d51..5699901f7d 100644
+--- a/crypto/evp/c_allc.c
++++ b/crypto/evp/c_allc.c
+@@ -261,6 +261,7 @@ void openssl_add_all_ciphers_int(void)
+ EVP_add_cipher(EVP_chacha20());
+ # ifndef OPENSSL_NO_POLY1305
+ EVP_add_cipher(EVP_chacha20_poly1305());
++ EVP_add_cipher(EVP_chacha20_poly1305_draft());
+ # endif
+ #endif
+ }
+diff --git a/crypto/evp/e_chacha20_poly1305.c b/crypto/evp/e_chacha20_poly1305.c
+index c1917bb86a..ea64c6b70e 100644
+--- a/crypto/evp/e_chacha20_poly1305.c
++++ b/crypto/evp/e_chacha20_poly1305.c
+@@ -154,6 +154,7 @@ typedef struct {
+ struct { uint64_t aad, text; } len;
+ int aad, mac_inited, tag_len, nonce_len;
+ size_t tls_payload_length;
++ unsigned char draft:1;
+ } EVP_CHACHA_AEAD_CTX;
+
+ # define NO_TLS_PAYLOAD_LENGTH ((size_t)-1)
+@@ -174,6 +175,7 @@ static int chacha20_poly1305_init_key(EVP_CIPHER_CTX *ctx,
+ actx->aad = 0;
+ actx->mac_inited = 0;
+ actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH;
++ actx->draft = 0;
+
+ if (iv != NULL) {
+ unsigned char temp[CHACHA_CTR_SIZE] = { 0 };
+@@ -195,6 +197,27 @@ static int chacha20_poly1305_init_key(EVP_CIPHER_CTX *ctx,
+ return 1;
+ }
+
++static int chacha20_poly1305_draft_init_key(EVP_CIPHER_CTX *ctx,
++ const unsigned char *inkey,
++ const unsigned char *iv, int enc)
++{
++ EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
++
++ if (!inkey)
++ return 1;
++
++ actx->len.aad = 0;
++ actx->len.text = 0;
++ actx->aad = 0;
++ actx->mac_inited = 0;
++ actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH;
++ actx->draft = 1;
++
++ chacha_init_key(ctx, inkey, NULL, enc);
++
++ return 1;
++}
++
+ # if !defined(OPENSSL_SMALL_FOOTPRINT)
+
+ # if defined(POLY1305_ASM) && (defined(__x86_64) || defined(__x86_64__) || \
+@@ -365,10 +388,11 @@ static int chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ {
+ EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx);
+ size_t rem, plen = actx->tls_payload_length;
++ uint64_t thirteen = EVP_AEAD_TLS1_AAD_LEN;
+
+ if (!actx->mac_inited) {
+ # if !defined(OPENSSL_SMALL_FOOTPRINT)
+- if (plen != NO_TLS_PAYLOAD_LENGTH && out != NULL)
++ if (plen != NO_TLS_PAYLOAD_LENGTH && out != NULL && !actx->draft)
+ return chacha20_poly1305_tls_cipher(ctx, out, in, len);
+ # endif
+ actx->key.counter[0] = 0;
+@@ -395,9 +419,14 @@ static int chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ return len;
+ } else { /* plain- or ciphertext */
+ if (actx->aad) { /* wrap up aad */
+- if ((rem = (size_t)actx->len.aad % POLY1305_BLOCK_SIZE))
+- Poly1305_Update(POLY1305_ctx(actx), zero,
+- POLY1305_BLOCK_SIZE - rem);
++ if (actx->draft) {
++ thirteen = actx->len.aad;
++ Poly1305_Update(POLY1305_ctx(actx), (const unsigned char *)&thirteen, sizeof(thirteen));
++ } else {
++ if ((rem = (size_t)actx->len.aad % POLY1305_BLOCK_SIZE))
++ Poly1305_Update(POLY1305_ctx(actx), zero,
++ POLY1305_BLOCK_SIZE - rem);
++ }
+ actx->aad = 0;
+ }
+
+@@ -430,40 +459,52 @@ static int chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+ } is_endian = { 1 };
+ unsigned char temp[POLY1305_BLOCK_SIZE];
+
++ if (actx->draft) {
++ thirteen = actx->len.text;
++ Poly1305_Update(POLY1305_ctx(actx), (const unsigned char *)&thirteen, sizeof(thirteen));
++ }
++
+ if (actx->aad) { /* wrap up aad */
+- if ((rem = (size_t)actx->len.aad % POLY1305_BLOCK_SIZE))
+- Poly1305_Update(POLY1305_ctx(actx), zero,
+- POLY1305_BLOCK_SIZE - rem);
++ if (actx->draft) {
++ thirteen = actx->len.aad;
++ Poly1305_Update(POLY1305_ctx(actx), (const unsigned char *)&thirteen, sizeof(thirteen));
++ } else {
++ if ((rem = (size_t)actx->len.aad % POLY1305_BLOCK_SIZE))
++ Poly1305_Update(POLY1305_ctx(actx), zero,
++ POLY1305_BLOCK_SIZE - rem);
++ }
+ actx->aad = 0;
+ }
+
+- if ((rem = (size_t)actx->len.text % POLY1305_BLOCK_SIZE))
+- Poly1305_Update(POLY1305_ctx(actx), zero,
+- POLY1305_BLOCK_SIZE - rem);
++ if (!actx->draft) {
++ if ((rem = (size_t)actx->len.text % POLY1305_BLOCK_SIZE))
++ Poly1305_Update(POLY1305_ctx(actx), zero,
++ POLY1305_BLOCK_SIZE - rem);
+
+- if (is_endian.little) {
+- Poly1305_Update(POLY1305_ctx(actx),
+- (unsigned char *)&actx->len, POLY1305_BLOCK_SIZE);
+- } else {
+- temp[0] = (unsigned char)(actx->len.aad);
+- temp[1] = (unsigned char)(actx->len.aad>>8);
+- temp[2] = (unsigned char)(actx->len.aad>>16);
+- temp[3] = (unsigned char)(actx->len.aad>>24);
+- temp[4] = (unsigned char)(actx->len.aad>>32);
+- temp[5] = (unsigned char)(actx->len.aad>>40);
+- temp[6] = (unsigned char)(actx->len.aad>>48);
+- temp[7] = (unsigned char)(actx->len.aad>>56);
+-
+- temp[8] = (unsigned char)(actx->len.text);
+- temp[9] = (unsigned char)(actx->len.text>>8);
+- temp[10] = (unsigned char)(actx->len.text>>16);
+- temp[11] = (unsigned char)(actx->len.text>>24);
+- temp[12] = (unsigned char)(actx->len.text>>32);
+- temp[13] = (unsigned char)(actx->len.text>>40);
+- temp[14] = (unsigned char)(actx->len.text>>48);
+- temp[15] = (unsigned char)(actx->len.text>>56);
+-
+- Poly1305_Update(POLY1305_ctx(actx), temp, POLY1305_BLOCK_SIZE);
++ if (is_endian.little) {
++ Poly1305_Update(POLY1305_ctx(actx),
++ (unsigned char *)&actx->len, POLY1305_BLOCK_SIZE);
++ } else {
++ temp[0] = (unsigned char)(actx->len.aad);
++ temp[1] = (unsigned char)(actx->len.aad>>8);
++ temp[2] = (unsigned char)(actx->len.aad>>16);
++ temp[3] = (unsigned char)(actx->len.aad>>24);
++ temp[4] = (unsigned char)(actx->len.aad>>32);
++ temp[5] = (unsigned char)(actx->len.aad>>40);
++ temp[6] = (unsigned char)(actx->len.aad>>48);
++ temp[7] = (unsigned char)(actx->len.aad>>56);
++
++ temp[8] = (unsigned char)(actx->len.text);
++ temp[9] = (unsigned char)(actx->len.text>>8);
++ temp[10] = (unsigned char)(actx->len.text>>16);
++ temp[11] = (unsigned char)(actx->len.text>>24);
++ temp[12] = (unsigned char)(actx->len.text>>32);
++ temp[13] = (unsigned char)(actx->len.text>>40);
++ temp[14] = (unsigned char)(actx->len.text>>48);
++ temp[15] = (unsigned char)(actx->len.text>>56);
++
++ Poly1305_Update(POLY1305_ctx(actx), temp, POLY1305_BLOCK_SIZE);
++ }
+ }
+ Poly1305_Final(POLY1305_ctx(actx), ctx->encrypt ? actx->tag
+ : temp);
+@@ -533,12 +574,14 @@ static int chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
+ return 1;
+
+ case EVP_CTRL_AEAD_SET_IVLEN:
++ if (actx->draft) return -1;
+ if (arg <= 0 || arg > CHACHA_CTR_SIZE)
+ return 0;
+ actx->nonce_len = arg;
+ return 1;
+
+ case EVP_CTRL_AEAD_SET_IV_FIXED:
++ if (actx->draft) return -1;
+ if (arg != 12)
+ return 0;
+ actx->nonce[0] = actx->key.counter[1]
+@@ -622,9 +665,32 @@ static EVP_CIPHER chacha20_poly1305 = {
+ NULL /* app_data */
+ };
+
++static EVP_CIPHER chacha20_poly1305_draft = {
++ NID_chacha20_poly1305_draft,
++ 1, /* block_size */
++ CHACHA_KEY_SIZE, /* key_len */
++ 0, /* iv_len, none */
++ EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_CUSTOM_IV |
++ EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT |
++ EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_CUSTOM_CIPHER,
++ chacha20_poly1305_draft_init_key,
++ chacha20_poly1305_cipher,
++ chacha20_poly1305_cleanup,
++ 0, /* 0 moves context-specific structure allocation to ctrl */
++ NULL, /* set_asn1_parameters */
++ NULL, /* get_asn1_parameters */
++ chacha20_poly1305_ctrl,
++ NULL /* app_data */
++};
++
+ const EVP_CIPHER *EVP_chacha20_poly1305(void)
+ {
+ return(&chacha20_poly1305);
+ }
++
++const EVP_CIPHER *EVP_chacha20_poly1305_draft(void)
++{
++ return(&chacha20_poly1305_draft);
++}
+ # endif
+ #endif
+diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h
+index e931f7f516..c1cf32b2b0 100644
+--- a/crypto/objects/obj_dat.h
++++ b/crypto/objects/obj_dat.h
+@@ -1078,7 +1078,7 @@ static const unsigned char so[7762] = {
+ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0D, /* [ 7753] OBJ_hmacWithSHA512_256 */
+ };
+
+-#define NUM_NID 1195
++#define NUM_NID 1196
+ static const ASN1_OBJECT nid_objs[NUM_NID] = {
+ {"UNDEF", "undefined", NID_undef},
+ {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
+@@ -2275,9 +2275,10 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = {
+ {"magma-mac", "magma-mac", NID_magma_mac},
+ {"hmacWithSHA512-224", "hmacWithSHA512-224", NID_hmacWithSHA512_224, 8, &so[7745]},
+ {"hmacWithSHA512-256", "hmacWithSHA512-256", NID_hmacWithSHA512_256, 8, &so[7753]},
++ {"ChaCha20-Poly1305-D", "chacha20-poly1305-draft", NID_chacha20_poly1305_draft },
+ };
+
+-#define NUM_SN 1186
++#define NUM_SN 1187
+ static const unsigned int sn_objs[NUM_SN] = {
+ 364, /* "AD_DVCS" */
+ 419, /* "AES-128-CBC" */
+@@ -2395,6 +2396,7 @@ static const unsigned int sn_objs[NUM_SN] = {
+ 417, /* "CSPName" */
+ 1019, /* "ChaCha20" */
+ 1018, /* "ChaCha20-Poly1305" */
++ 1195, /* "chacha20-poly1305-draft" */
+ 367, /* "CrlID" */
+ 391, /* "DC" */
+ 31, /* "DES-CBC" */
+@@ -3467,7 +3469,7 @@ static const unsigned int sn_objs[NUM_SN] = {
+ 1093, /* "x509ExtAdmission" */
+ };
+
+-#define NUM_LN 1186
++#define NUM_LN 1187
+ static const unsigned int ln_objs[NUM_LN] = {
+ 363, /* "AD Time Stamping" */
+ 405, /* "ANSI X9.62" */
+@@ -3846,6 +3848,7 @@ static const unsigned int ln_objs[NUM_LN] = {
+ 883, /* "certificateRevocationList" */
+ 1019, /* "chacha20" */
+ 1018, /* "chacha20-poly1305" */
++ 1195, /* "ChaCha20-Poly1305-D" */
+ 54, /* "challengePassword" */
+ 407, /* "characteristic-two-field" */
+ 395, /* "clearance" */
+diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num
+index 1b6a9c61a1..a55fc456ee 100644
+--- a/crypto/objects/obj_mac.num
++++ b/crypto/objects/obj_mac.num
+@@ -1192,3 +1192,4 @@ magma_cfb 1191
+ magma_mac 1192
+ hmacWithSHA512_224 1193
+ hmacWithSHA512_256 1194
++chacha20_poly1305_draft 1195
+diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt
+index 6dbc41ce37..581169eda8 100644
+--- a/crypto/objects/objects.txt
++++ b/crypto/objects/objects.txt
+@@ -1534,6 +1534,7 @@ sm-scheme 104 7 : SM4-CTR : sm4-ctr
+ : AES-192-CBC-HMAC-SHA256 : aes-192-cbc-hmac-sha256
+ : AES-256-CBC-HMAC-SHA256 : aes-256-cbc-hmac-sha256
+ : ChaCha20-Poly1305 : chacha20-poly1305
++ : ChaCha20-Poly1305-D : chacha20-poly1305-draft
+ : ChaCha20 : chacha20
+
+ ISO-US 10046 2 1 : dhpublicnumber : X9.42 DH
+diff --git a/include/openssl/evp.h b/include/openssl/evp.h
+index 8c8051993f..69011983af 100644
+--- a/include/openssl/evp.h
++++ b/include/openssl/evp.h
+@@ -915,6 +915,7 @@ const EVP_CIPHER *EVP_camellia_256_ctr(void);
+ const EVP_CIPHER *EVP_chacha20(void);
+ # ifndef OPENSSL_NO_POLY1305
+ const EVP_CIPHER *EVP_chacha20_poly1305(void);
++const EVP_CIPHER *EVP_chacha20_poly1305_draft(void);
+ # endif
+ # endif
+
+diff --git a/include/openssl/obj_mac.h b/include/openssl/obj_mac.h
+index 80ff5a7c86..456e05ffea 100644
+--- a/include/openssl/obj_mac.h
++++ b/include/openssl/obj_mac.h
+@@ -4811,6 +4811,10 @@
+ #define LN_chacha20 "chacha20"
+ #define NID_chacha20 1019
+
++#define SN_chacha20_poly1305_draft "ChaCha20-Poly1305-D"
++#define LN_chacha20_poly1305_draft "chacha20-poly1305-draft"
++#define NID_chacha20_poly1305_draft 1195
++
+ #define SN_dhpublicnumber "dhpublicnumber"
+ #define LN_dhpublicnumber "X9.42 DH"
+ #define NID_dhpublicnumber 920
+diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
+index ffe158388d..54dcd2702f 100644
+--- a/include/openssl/ssl.h
++++ b/include/openssl/ssl.h
+@@ -125,6 +125,7 @@ extern "C" {
+ # define SSL_TXT_CAMELLIA256 "CAMELLIA256"
+ # define SSL_TXT_CAMELLIA "CAMELLIA"
+ # define SSL_TXT_CHACHA20 "CHACHA20"
++# define SSL_TXT_CHACHA20_D "CHACHA20-D"
+ # define SSL_TXT_GOST "GOST89"
+ # define SSL_TXT_ARIA "ARIA"
+ # define SSL_TXT_ARIA_GCM "ARIAGCM"
+diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h
+index 2e46cf80d3..cc750bf735 100644
+--- a/include/openssl/tls1.h
++++ b/include/openssl/tls1.h
+@@ -596,7 +596,12 @@ __owur int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain)
+ # define TLS1_CK_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 0x0300C09A
+ # define TLS1_CK_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 0x0300C09B
+
+-/* draft-ietf-tls-chacha20-poly1305-03 */
++/* Chacha20-Poly1305-Draft ciphersuites from draft-agl-tls-chacha20poly1305-04 */
++# define TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_D 0x0300CC13
++# define TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_D 0x0300CC14
++# define TLS1_CK_DHE_RSA_WITH_CHACHA20_POLY1305_D 0x0300CC15
++
++/* Chacha20-Poly1305 ciphersuites from RFC7905 */
+ # define TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305 0x0300CCA8
+ # define TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 0x0300CCA9
+ # define TLS1_CK_DHE_RSA_WITH_CHACHA20_POLY1305 0x0300CCAA
+@@ -761,6 +766,9 @@ __owur int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain)
+ # define TLS1_RFC_DHE_RSA_WITH_CHACHA20_POLY1305 "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256"
+ # define TLS1_RFC_ECDHE_RSA_WITH_CHACHA20_POLY1305 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"
+ # define TLS1_RFC_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"
++# define TLS1_RFC_DHE_RSA_WITH_CHACHA20_POLY1305_D "OLD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256"
++# define TLS1_RFC_ECDHE_RSA_WITH_CHACHA20_POLY1305_D "OLD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"
++# define TLS1_RFC_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_D "OLD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"
+ # define TLS1_RFC_PSK_WITH_CHACHA20_POLY1305 "TLS_PSK_WITH_CHACHA20_POLY1305_SHA256"
+ # define TLS1_RFC_ECDHE_PSK_WITH_CHACHA20_POLY1305 "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256"
+ # define TLS1_RFC_DHE_PSK_WITH_CHACHA20_POLY1305 "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256"
+@@ -1089,7 +1097,12 @@ __owur int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain)
+ # define TLS1_TXT_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 "ECDH-RSA-CAMELLIA128-SHA256"
+ # define TLS1_TXT_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 "ECDH-RSA-CAMELLIA256-SHA384"
+
+-/* draft-ietf-tls-chacha20-poly1305-03 */
++/* Chacha20-Poly1305-Draft ciphersuites from draft-agl-tls-chacha20poly1305-04 */
++# define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_D "ECDHE-RSA-CHACHA20-POLY1305-OLD"
++# define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_D "ECDHE-ECDSA-CHACHA20-POLY1305-OLD"
++# define TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305_D "DHE-RSA-CHACHA20-POLY1305-OLD"
++
++/* Chacha20-Poly1305 ciphersuites from RFC7905 */
+ # define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305 "ECDHE-RSA-CHACHA20-POLY1305"
+ # define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 "ECDHE-ECDSA-CHACHA20-POLY1305"
+ # define TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305 "DHE-RSA-CHACHA20-POLY1305"
+diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
+index 7713f767b2..cb37dd6e6f 100644
+--- a/ssl/s3_lib.c
++++ b/ssl/s3_lib.c
+@@ -2082,6 +2082,54 @@ static SSL_CIPHER ssl3_ciphers[] = {
+ 256,
+ 256,
+ },
++ {
++ 1,
++ TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305_D,
++ TLS1_RFC_DHE_RSA_WITH_CHACHA20_POLY1305_D,
++ TLS1_CK_DHE_RSA_WITH_CHACHA20_POLY1305_D,
++ SSL_kDHE,
++ SSL_aRSA,
++ SSL_CHACHA20POLY1305_D,
++ SSL_AEAD,
++ TLS1_2_VERSION, TLS1_2_VERSION,
++ DTLS1_2_VERSION, DTLS1_2_VERSION,
++ SSL_HIGH,
++ SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
++ 256,
++ 256,
++ },
++ {
++ 1,
++ TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_D,
++ TLS1_RFC_ECDHE_RSA_WITH_CHACHA20_POLY1305_D,
++ TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_D,
++ SSL_kECDHE,
++ SSL_aRSA,
++ SSL_CHACHA20POLY1305_D,
++ SSL_AEAD,
++ TLS1_2_VERSION, TLS1_2_VERSION,
++ DTLS1_2_VERSION, DTLS1_2_VERSION,
++ SSL_HIGH,
++ SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
++ 256,
++ 256,
++ },
++ {
++ 1,
++ TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_D,
++ TLS1_RFC_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_D,
++ TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_D,
++ SSL_kECDHE,
++ SSL_aECDSA,
++ SSL_CHACHA20POLY1305_D,
++ SSL_AEAD,
++ TLS1_2_VERSION, TLS1_2_VERSION,
++ DTLS1_2_VERSION, DTLS1_2_VERSION,
++ SSL_HIGH,
++ SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
++ 256,
++ 256,
++ },
+ {
+ 1,
+ TLS1_TXT_PSK_WITH_CHACHA20_POLY1305,
+diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
+index 14066d0ea4..0ded2bd6b6 100644
+--- a/ssl/ssl_ciph.c
++++ b/ssl/ssl_ciph.c
+@@ -43,7 +43,8 @@
+ #define SSL_ENC_CHACHA_IDX 19
+ #define SSL_ENC_ARIA128GCM_IDX 20
+ #define SSL_ENC_ARIA256GCM_IDX 21
+-#define SSL_ENC_NUM_IDX 22
++#define SSL_ENC_CHACHA20_D_IDX 22
++#define SSL_ENC_NUM_IDX 23
+
+ /* NB: make sure indices in these tables match values above */
+
+@@ -76,6 +77,7 @@ static const ssl_cipher_table ssl_cipher_table_cipher[SSL_ENC_NUM_IDX] = {
+ {SSL_CHACHA20POLY1305, NID_chacha20_poly1305}, /* SSL_ENC_CHACHA_IDX 19 */
+ {SSL_ARIA128GCM, NID_aria_128_gcm}, /* SSL_ENC_ARIA128GCM_IDX 20 */
+ {SSL_ARIA256GCM, NID_aria_256_gcm}, /* SSL_ENC_ARIA256GCM_IDX 21 */
++ {SSL_CHACHA20POLY1305_D, NID_chacha20_poly1305_draft}, /* SSL_ENC_CHACHA20POLY1305_IDX 22 */
+ };
+
+ static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX];
+@@ -273,6 +275,7 @@ static const SSL_CIPHER cipher_aliases[] = {
+ {0, SSL_TXT_CAMELLIA256, NULL, 0, 0, 0, SSL_CAMELLIA256},
+ {0, SSL_TXT_CAMELLIA, NULL, 0, 0, 0, SSL_CAMELLIA},
+ {0, SSL_TXT_CHACHA20, NULL, 0, 0, 0, SSL_CHACHA20},
++ {0, SSL_TXT_CHACHA20_D, NULL, 0, 0, 0, SSL_CHACHA20POLY1305_D},
+
+ {0, SSL_TXT_ARIA, NULL, 0, 0, 0, SSL_ARIA},
+ {0, SSL_TXT_ARIA_GCM, NULL, 0, 0, 0, SSL_ARIA128GCM | SSL_ARIA256GCM},
+@@ -1789,6 +1792,9 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
+ case SSL_CHACHA20POLY1305:
+ enc = "CHACHA20/POLY1305(256)";
+ break;
++ case SSL_CHACHA20POLY1305_D:
++ enc = "CHACHA20/POLY1305-Draft(256)";
++ break;
+ default:
+ enc = "unknown";
+ break;
+@@ -2113,7 +2119,7 @@ int ssl_cipher_get_overhead(const SSL_CIPHER *c, size_t *mac_overhead,
+ out = EVP_CCM_TLS_EXPLICIT_IV_LEN + 16;
+ } else if (c->algorithm_enc & (SSL_AES128CCM8 | SSL_AES256CCM8)) {
+ out = EVP_CCM_TLS_EXPLICIT_IV_LEN + 8;
+- } else if (c->algorithm_enc & SSL_CHACHA20POLY1305) {
++ } else if (c->algorithm_enc & (SSL_CHACHA20POLY1305 | SSL_CHACHA20POLY1305_D)) {
+ out = 16;
+ } else if (c->algorithm_mac & SSL_AEAD) {
+ /* We're supposed to have handled all the AEAD modes above */
+diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
+index c22c1f9ee8..6c4595c49b 100644
+--- a/ssl/ssl_locl.h
++++ b/ssl/ssl_locl.h
+@@ -230,12 +230,13 @@
+ # define SSL_CHACHA20POLY1305 0x00080000U
+ # define SSL_ARIA128GCM 0x00100000U
+ # define SSL_ARIA256GCM 0x00200000U
++# define SSL_CHACHA20POLY1305_D 0x00400000U
+
+ # define SSL_AESGCM (SSL_AES128GCM | SSL_AES256GCM)
+ # define SSL_AESCCM (SSL_AES128CCM | SSL_AES256CCM | SSL_AES128CCM8 | SSL_AES256CCM8)
+ # define SSL_AES (SSL_AES128|SSL_AES256|SSL_AESGCM|SSL_AESCCM)
+ # define SSL_CAMELLIA (SSL_CAMELLIA128|SSL_CAMELLIA256)
+-# define SSL_CHACHA20 (SSL_CHACHA20POLY1305)
++# define SSL_CHACHA20 (SSL_CHACHA20POLY1305 | SSL_CHACHA20POLY1305_D)
+ # define SSL_ARIAGCM (SSL_ARIA128GCM | SSL_ARIA256GCM)
+ # define SSL_ARIA (SSL_ARIAGCM)
+
+diff --git a/util/libcrypto.num b/util/libcrypto.num
+index ecece3824f..678b04c9ed 100644
+--- a/util/libcrypto.num
++++ b/util/libcrypto.num
+@@ -4577,3 +4577,4 @@ OCSP_resp_get0_respdata 4530 1_1_0j EXIST::FUNCTION:OCSP
+ EVP_MD_CTX_set_pkey_ctx 4531 1_1_1 EXIST::FUNCTION:
+ EVP_PKEY_meth_set_digest_custom 4532 1_1_1 EXIST::FUNCTION:
+ EVP_PKEY_meth_get_digest_custom 4533 1_1_1 EXIST::FUNCTION:
++EVP_chacha20_poly1305_draft 4534 1_1_0 EXIST::FUNCTION:CHACHA,POLY1305_DRAFT