ChaCha20-Poly1305 support.
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 96b3a01..ae73161 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -1605,7 +1605,7 @@
 	SSL_AEAD,
 	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4),
+	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)|SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
 	128,
 	128,
 	},
@@ -1637,7 +1637,7 @@
 	SSL_AEAD,
 	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4),
+	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)|SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
 	128,
 	128,
 	},
@@ -1669,7 +1669,7 @@
 	SSL_AEAD,
 	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4),
+	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)|SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
 	128,
 	128,
 	},
@@ -1701,7 +1701,7 @@
 	SSL_AEAD,
 	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4),
+	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)|SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
 	128,
 	128,
 	},
@@ -1733,7 +1733,7 @@
 	SSL_AEAD,
 	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4),
+	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)|SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
 	128,
 	128,
 	},
@@ -1765,7 +1765,7 @@
 	SSL_AEAD,
 	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4),
+	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)|SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
 	128,
 	128,
 	},
@@ -2349,7 +2349,7 @@
 	SSL_AEAD,
 	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4),
+	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)|SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
 	128,
 	128,
 	},
@@ -2381,7 +2381,7 @@
 	SSL_AEAD,
 	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4),
+	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)|SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
 	128,
 	128,
 	},
@@ -2413,7 +2413,7 @@
 	SSL_AEAD,
 	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4),
+	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)|SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
 	128,
 	128,
 	},
@@ -2445,7 +2445,7 @@
 	SSL_AEAD,
 	SSL_TLSV1_2,
 	SSL_NOT_EXP|SSL_HIGH|SSL_FIPS,
-	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4),
+	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(4)|SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
 	128,
 	128,
 	},
@@ -2529,6 +2529,51 @@
 	},
 #endif
 
+	{
+	1,
+	TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+	TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305,
+	SSL_kEECDH,
+	SSL_aRSA,
+	SSL_CHACHA20POLY1305,
+	SSL_AEAD,
+	SSL_TLSV1_2,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(0),
+	256,
+	0,
+	},
+
+	{
+	1,
+	TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
+	TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305,
+	SSL_kEECDH,
+	SSL_aECDSA,
+	SSL_CHACHA20POLY1305,
+	SSL_AEAD,
+	SSL_TLSV1_2,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(0),
+	256,
+	0,
+	},
+
+	{
+	1,
+	TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305,
+	TLS1_CK_DHE_RSA_CHACHA20_POLY1305,
+	SSL_kEDH,
+	SSL_aRSA,
+	SSL_CHACHA20POLY1305,
+	SSL_AEAD,
+	SSL_TLSV1_2,
+	SSL_NOT_EXP|SSL_HIGH,
+	SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256|SSL_CIPHER_ALGORITHM2_AEAD|FIXED_NONCE_LEN(0),
+	256,
+	0,
+	},
+
 /* end of list */
 	};
 
diff --git a/ssl/s3_pkt.c b/ssl/s3_pkt.c
index c244724..563f96e 100644
--- a/ssl/s3_pkt.c
+++ b/ssl/s3_pkt.c
@@ -765,8 +765,11 @@
 		else
 			eivlen = 0;
 		}
-	else if (s->aead_write_ctx != NULL)
+	else if (s->aead_write_ctx != NULL &&
+		 s->aead_write_ctx->variable_nonce_included_in_record)
+		{
 		eivlen = s->aead_write_ctx->variable_nonce_len;
+		}
 	else
 		eivlen = 0;
 
diff --git a/ssl/ssl.h b/ssl/ssl.h
index 5c0626c..bf978a0 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -281,6 +281,7 @@
 #define SSL_TXT_CAMELLIA128	"CAMELLIA128"
 #define SSL_TXT_CAMELLIA256	"CAMELLIA256"
 #define SSL_TXT_CAMELLIA	"CAMELLIA"
+#define SSL_TXT_CHACHA20	"CHACHA20"
 
 #define SSL_TXT_MD5		"MD5"
 #define SSL_TXT_SHA1		"SHA1"
@@ -2258,6 +2259,7 @@
 int SSL_CIPHER_is_AES(const SSL_CIPHER *c);
 int SSL_CIPHER_has_MD5_HMAC(const SSL_CIPHER *c);
 int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *c);
+int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *c);
 
 /* This sets the 'default' SSL version that SSL_new() will create */
 int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth);
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index e235020..2cee44c 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -296,6 +296,7 @@
 	{0,SSL_TXT_CAMELLIA128,0,0,0,SSL_CAMELLIA128,0,0,0,0,0,0},
 	{0,SSL_TXT_CAMELLIA256,0,0,0,SSL_CAMELLIA256,0,0,0,0,0,0},
 	{0,SSL_TXT_CAMELLIA   ,0,0,0,SSL_CAMELLIA128|SSL_CAMELLIA256,0,0,0,0,0,0},
+	{0,SSL_TXT_CHACHA20   ,0,0,0,SSL_CHACHA20POLY1305,0,0,0,0,0,0},
 
 	/* MAC aliases */	
 	{0,SSL_TXT_MD5,0,     0,0,0,SSL_MD5,   0,0,0,0,0},
@@ -385,9 +386,15 @@
 		return 0;
 
 #ifndef OPENSSL_NO_AES
-	/* There is only one AEAD for now. */
-	*aead = EVP_aead_aes_128_gcm();
-	return 1;
+	switch (c->algorithm_enc)
+		{
+	case SSL_AES128GCM:
+		*aead = EVP_aead_aes_128_gcm();
+		return 1;
+	case SSL_CHACHA20POLY1305:
+		*aead = EVP_aead_chacha20_poly1305();
+		return 1;
+		}
 #endif
 
 	return 0;
@@ -1621,6 +1628,9 @@
 	case SSL_SEED:
 		enc="SEED(128)";
 		break;
+	case SSL_CHACHA20POLY1305:
+		enc="ChaCha20-Poly1305";
+		break;
 	default:
 		enc="unknown";
 		break;
@@ -1681,6 +1691,11 @@
 	return (c->algorithm_mac & (SSL_AES128GCM|SSL_AES256GCM)) != 0;
 	}
 
+int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *c)
+	{
+	return (c->algorithm_enc & SSL_CHACHA20POLY1305) != 0;
+	}
+
 char *SSL_CIPHER_get_version(const SSL_CIPHER *c)
 	{
 	int i;
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 22637a1..ed25099 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -316,6 +316,7 @@
 #define SSL_SEED		0x00000800L
 #define SSL_AES128GCM		0x00001000L
 #define SSL_AES256GCM		0x00002000L
+#define SSL_CHACHA20POLY1305	0x00004000L
 
 #define SSL_AES        		(SSL_AES128|SSL_AES256|SSL_AES128GCM|SSL_AES256GCM)
 #define SSL_CAMELLIA		(SSL_CAMELLIA128|SSL_CAMELLIA256)
@@ -377,6 +378,12 @@
 #define SSL_CIPHER_AEAD_FIXED_NONCE_LEN(ssl_cipher) \
 	(((ssl_cipher->algorithm2 >> 24) & 0xf)*2)
 
+/* SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD is a flag in
+ * SSL_CIPHER.algorithm2 which indicates that the variable part of the nonce is
+ * included as a prefix of the record. (AES-GCM, for example, does with with an
+ * 8-byte variable nonce.) */
+#define SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD (1<<22)
+
 /*
  * Export and cipher strength information. For each cipher we have to decide
  * whether it is exportable or not. This information is likely to change
@@ -747,6 +754,9 @@
 	 * records. */
 	unsigned char fixed_nonce[8];
 	unsigned char fixed_nonce_len, variable_nonce_len, tag_len;
+	/* variable_nonce_included_in_record is non-zero if the variable nonce
+	 * for a record is included as a prefix before the ciphertext. */
+	char variable_nonce_included_in_record;
 	};
 
 #ifndef OPENSSL_NO_COMP
diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c
index 58f8bf8..7897519 100644
--- a/ssl/t1_enc.c
+++ b/ssl/t1_enc.c
@@ -361,6 +361,8 @@
 	memcpy(aead_ctx->fixed_nonce, iv, iv_len);
 	aead_ctx->fixed_nonce_len = iv_len;
 	aead_ctx->variable_nonce_len = 8;  /* always the case, currently. */
+	aead_ctx->variable_nonce_included_in_record =
+		(s->s3->tmp.new_cipher->algorithm2 & SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD) != 0;
 	if (aead_ctx->variable_nonce_len + aead_ctx->fixed_nonce_len != EVP_AEAD_nonce_length(aead))
 		{
 		OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state_aead, ERR_R_INTERNAL_ERROR);
@@ -822,6 +824,7 @@
 		if (send)
 			{
 			size_t len = rec->length;
+			size_t eivlen = 0;
 			in = rec->input;
 			out = rec->data;
 
@@ -837,22 +840,27 @@
 			 * variable nonce. Thus we can copy the sequence number
 			 * bytes into place without overwriting any of the
 			 * plaintext. */
-			memcpy(out, ad, aead->variable_nonce_len);
-			len -= aead->variable_nonce_len;
+			if (aead->variable_nonce_included_in_record)
+				{
+				memcpy(out, ad, aead->variable_nonce_len);
+				len -= aead->variable_nonce_len;
+				eivlen = aead->variable_nonce_len;
+				}
 
 			ad[11] = len >> 8;
 			ad[12] = len & 0xff;
 
 			if (!EVP_AEAD_CTX_seal(
 				&aead->ctx,
-				out + aead->variable_nonce_len, &n, len + aead->tag_len,
+				out + eivlen, &n, len + aead->tag_len,
 				nonce, nonce_used,
-				in + aead->variable_nonce_len, len,
+				in + eivlen, len,
 				ad, sizeof(ad)))
 				{
 				return -1;
 				}
-			n += aead->variable_nonce_len;
+			if (aead->variable_nonce_included_in_record)
+				n += aead->variable_nonce_len;
 			}
 		else
 			{
@@ -865,12 +873,17 @@
 
 			if (len < aead->variable_nonce_len)
 				return 0;
-			memcpy(nonce + nonce_used, in, aead->variable_nonce_len);
+			memcpy(nonce + nonce_used,
+			       aead->variable_nonce_included_in_record ? in : ad,
+			       aead->variable_nonce_len);
 			nonce_used += aead->variable_nonce_len;
 
-			in += aead->variable_nonce_len;
-			len -= aead->variable_nonce_len;
-			out += aead->variable_nonce_len;
+			if (aead->variable_nonce_included_in_record)
+				{
+				in += aead->variable_nonce_len;
+				len -= aead->variable_nonce_len;
+				out += aead->variable_nonce_len;
+				}
 
 			if (len < aead->tag_len)
 				return 0;
diff --git a/ssl/tls1.h b/ssl/tls1.h
index 75de4c4..d09a6e3 100644
--- a/ssl/tls1.h
+++ b/ssl/tls1.h
@@ -567,6 +567,10 @@
 #define TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256        0x0300C031
 #define TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384        0x0300C032
 
+#define TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305		0x0300CC13
+#define TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305		0x0300CC14
+#define TLS1_CK_DHE_RSA_CHACHA20_POLY1305		0x0300CC15
+
 /* XXX
  * Inconsistency alert:
  * The OpenSSL names of ciphers with ephemeral DH here include the string
@@ -718,6 +722,10 @@
 #define TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256       "ECDH-RSA-AES128-GCM-SHA256"
 #define TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384       "ECDH-RSA-AES256-GCM-SHA384"
 
+#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"
+
 #define TLS_CT_RSA_SIGN			1
 #define TLS_CT_DSS_SIGN			2
 #define TLS_CT_RSA_FIXED_DH		3