|  | diff -pu a/nss/lib/ssl/ssl3con.c b/nss/lib/ssl/ssl3con.c | 
|  | --- a/nss/lib/ssl/ssl3con.c	2014-01-17 18:06:41.659713513 -0800 | 
|  | +++ b/nss/lib/ssl/ssl3con.c	2014-01-17 18:07:10.270188062 -0800 | 
|  | @@ -40,6 +40,21 @@ | 
|  | #define CKM_NSS_TLS_MASTER_KEY_DERIVE_DH_SHA256 (CKM_NSS + 24) | 
|  | #endif | 
|  |  | 
|  | +/* This is a bodge to allow this code to be compiled against older NSS | 
|  | + * headers. */ | 
|  | +#ifndef CKM_NSS_CHACHA20_POLY1305 | 
|  | +#define CKM_NSS_CHACHA20_POLY1305               (CKM_NSS + 26) | 
|  | + | 
|  | +typedef struct CK_NSS_AEAD_PARAMS { | 
|  | +    CK_BYTE_PTR  pIv;  /* This is the nonce. */ | 
|  | +    CK_ULONG     ulIvLen; | 
|  | +    CK_BYTE_PTR  pAAD; | 
|  | +    CK_ULONG     ulAADLen; | 
|  | +    CK_ULONG     ulTagLen; | 
|  | +} CK_NSS_AEAD_PARAMS; | 
|  | + | 
|  | +#endif | 
|  | + | 
|  | #include <stdio.h> | 
|  | #ifdef NSS_ENABLE_ZLIB | 
|  | #include "zlib.h" | 
|  | @@ -104,6 +119,8 @@ static ssl3CipherSuiteCfg cipherSuites[s | 
|  | /*      cipher_suite                     policy       enabled   isPresent */ | 
|  |  | 
|  | #ifdef NSS_ENABLE_ECC | 
|  | + { TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,  SSL_ALLOWED, PR_FALSE, PR_FALSE}, | 
|  | + { TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,    SSL_ALLOWED, PR_FALSE, PR_FALSE}, | 
|  | { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_FALSE, PR_FALSE}, | 
|  | { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,   SSL_ALLOWED, PR_FALSE, PR_FALSE}, | 
|  | /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA is out of order to work around | 
|  | @@ -292,6 +309,7 @@ static const ssl3BulkCipherDef bulk_ciph | 
|  | {cipher_camellia_256, calg_camellia,    32,32, type_block, 16,16, 0, 0}, | 
|  | {cipher_seed,         calg_seed,        16,16, type_block, 16,16, 0, 0}, | 
|  | {cipher_aes_128_gcm,  calg_aes_gcm,     16,16, type_aead,   4, 0,16, 8}, | 
|  | +    {cipher_chacha20,     calg_chacha20,    32,32, type_aead,   0, 0,16, 0}, | 
|  | {cipher_missing,      calg_null,         0, 0, type_stream, 0, 0, 0, 0}, | 
|  | }; | 
|  |  | 
|  | @@ -418,6 +436,8 @@ static const ssl3CipherSuiteDef cipher_s | 
|  | {TLS_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_rsa}, | 
|  | {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_ecdhe_rsa}, | 
|  | {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_ecdhe_ecdsa}, | 
|  | +    {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, cipher_chacha20, mac_aead, kea_ecdhe_rsa}, | 
|  | +    {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, cipher_chacha20, mac_aead, kea_ecdhe_ecdsa}, | 
|  |  | 
|  | #ifdef NSS_ENABLE_ECC | 
|  | {TLS_ECDH_ECDSA_WITH_NULL_SHA,        cipher_null, mac_sha, kea_ecdh_ecdsa}, | 
|  | @@ -483,6 +503,7 @@ static const SSLCipher2Mech alg2Mech[] = | 
|  | { calg_camellia , CKM_CAMELLIA_CBC			}, | 
|  | { calg_seed     , CKM_SEED_CBC			}, | 
|  | { calg_aes_gcm  , CKM_AES_GCM			}, | 
|  | +    { calg_chacha20 , CKM_NSS_CHACHA20_POLY1305		}, | 
|  | /*  { calg_init     , (CK_MECHANISM_TYPE)0x7fffffffL    }  */ | 
|  | }; | 
|  |  | 
|  | @@ -647,6 +668,8 @@ ssl3_CipherSuiteAllowedForVersionRange( | 
|  | *   SSL_DH_ANON_EXPORT_WITH_DES40_CBC_SHA:  never implemented | 
|  | */ | 
|  | return vrange->min <= SSL_LIBRARY_VERSION_TLS_1_0; | 
|  | +    case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305: | 
|  | +    case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: | 
|  | case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: | 
|  | case TLS_RSA_WITH_AES_256_CBC_SHA256: | 
|  | case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: | 
|  | @@ -2043,6 +2066,46 @@ ssl3_AESGCMBypass(ssl3KeyMaterial *keys, | 
|  | } | 
|  | #endif | 
|  |  | 
|  | +static SECStatus | 
|  | +ssl3_ChaCha20Poly1305( | 
|  | +	ssl3KeyMaterial *keys, | 
|  | +	PRBool doDecrypt, | 
|  | +	unsigned char *out, | 
|  | +	int *outlen, | 
|  | +	int maxout, | 
|  | +	const unsigned char *in, | 
|  | +	int inlen, | 
|  | +	const unsigned char *additionalData, | 
|  | +	int additionalDataLen) | 
|  | +{ | 
|  | +    SECItem            param; | 
|  | +    SECStatus          rv = SECFailure; | 
|  | +    unsigned int       uOutLen; | 
|  | +    CK_NSS_AEAD_PARAMS aeadParams; | 
|  | +    static const int   tagSize = 16; | 
|  | + | 
|  | +    param.type = siBuffer; | 
|  | +    param.len = sizeof(aeadParams); | 
|  | +    param.data = (unsigned char *) &aeadParams; | 
|  | +    memset(&aeadParams, 0, sizeof(aeadParams)); | 
|  | +    aeadParams.pIv = (unsigned char *) additionalData; | 
|  | +    aeadParams.ulIvLen = 8; | 
|  | +    aeadParams.pAAD = (unsigned char *) additionalData; | 
|  | +    aeadParams.ulAADLen = additionalDataLen; | 
|  | +    aeadParams.ulTagLen = tagSize; | 
|  | + | 
|  | +    if (doDecrypt) { | 
|  | +	rv = pk11_decrypt(keys->write_key, CKM_NSS_CHACHA20_POLY1305, ¶m, | 
|  | +			  out, &uOutLen, maxout, in, inlen); | 
|  | +    } else { | 
|  | +	rv = pk11_encrypt(keys->write_key, CKM_NSS_CHACHA20_POLY1305, ¶m, | 
|  | +			  out, &uOutLen, maxout, in, inlen); | 
|  | +    } | 
|  | +    *outlen = (int) uOutLen; | 
|  | + | 
|  | +    return rv; | 
|  | +} | 
|  | + | 
|  | /* Initialize encryption and MAC contexts for pending spec. | 
|  | * Master Secret already is derived. | 
|  | * Caller holds Spec write lock. | 
|  | @@ -2076,13 +2139,17 @@ ssl3_InitPendingContextsPKCS11(sslSocket | 
|  | pwSpec->client.write_mac_context = NULL; | 
|  | pwSpec->server.write_mac_context = NULL; | 
|  |  | 
|  | -    if (calg == calg_aes_gcm) { | 
|  | +    if (calg == calg_aes_gcm || calg == calg_chacha20) { | 
|  | pwSpec->encode = NULL; | 
|  | pwSpec->decode = NULL; | 
|  | pwSpec->destroy = NULL; | 
|  | pwSpec->encodeContext = NULL; | 
|  | pwSpec->decodeContext = NULL; | 
|  | -	pwSpec->aead = ssl3_AESGCM; | 
|  | +	if (calg == calg_aes_gcm) { | 
|  | +	    pwSpec->aead = ssl3_AESGCM; | 
|  | +	} else { | 
|  | +	    pwSpec->aead = ssl3_ChaCha20Poly1305; | 
|  | +	} | 
|  | return SECSuccess; | 
|  | } | 
|  |  | 
|  | diff -pu a/nss/lib/ssl/ssl3ecc.c b/nss/lib/ssl/ssl3ecc.c | 
|  | --- a/nss/lib/ssl/ssl3ecc.c	2014-01-17 18:04:43.127747463 -0800 | 
|  | +++ b/nss/lib/ssl/ssl3ecc.c	2014-01-17 18:07:10.270188062 -0800 | 
|  | @@ -904,6 +904,7 @@ static const ssl3CipherSuite ecdhe_ecdsa | 
|  | TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, | 
|  | TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, | 
|  | TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, | 
|  | +    TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, | 
|  | TLS_ECDHE_ECDSA_WITH_NULL_SHA, | 
|  | TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, | 
|  | 0 /* end of list marker */ | 
|  | @@ -915,6 +916,7 @@ static const ssl3CipherSuite ecdhe_rsa_s | 
|  | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, | 
|  | TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, | 
|  | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, | 
|  | +    TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, | 
|  | TLS_ECDHE_RSA_WITH_NULL_SHA, | 
|  | TLS_ECDHE_RSA_WITH_RC4_128_SHA, | 
|  | 0 /* end of list marker */ | 
|  | @@ -927,6 +929,7 @@ static const ssl3CipherSuite ecSuites[] | 
|  | TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, | 
|  | TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, | 
|  | TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, | 
|  | +    TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, | 
|  | TLS_ECDHE_ECDSA_WITH_NULL_SHA, | 
|  | TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, | 
|  | TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, | 
|  | @@ -934,6 +937,7 @@ static const ssl3CipherSuite ecSuites[] | 
|  | TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, | 
|  | TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, | 
|  | TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, | 
|  | +    TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, | 
|  | TLS_ECDHE_RSA_WITH_NULL_SHA, | 
|  | TLS_ECDHE_RSA_WITH_RC4_128_SHA, | 
|  | TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, | 
|  | diff -pu a/nss/lib/ssl/sslenum.c b/nss/lib/ssl/sslenum.c | 
|  | --- a/nss/lib/ssl/sslenum.c	2014-01-17 17:49:26.072517368 -0800 | 
|  | +++ b/nss/lib/ssl/sslenum.c	2014-01-17 18:08:43.791739267 -0800 | 
|  | @@ -37,17 +37,21 @@ | 
|  | * | 
|  | * Exception: Because some servers ignore the high-order byte of the cipher | 
|  | * suite ID, we must be careful about adding cipher suites with IDs larger | 
|  | - * than 0x00ff; see bug 946147. For these broken servers, the first four cipher | 
|  | + * than 0x00ff; see bug 946147. For these broken servers, the first six cipher | 
|  | * suites, with the MSB zeroed, look like: | 
|  | + *      TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA { 0x00,0x14 } | 
|  | + *      TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA { 0x00,0x13 } | 
|  | *      TLS_KRB5_EXPORT_WITH_RC4_40_MD5 { 0x00,0x2B } | 
|  | *      TLS_RSA_WITH_AES_128_CBC_SHA { 0x00,0x2F } | 
|  | *      TLS_RSA_WITH_3DES_EDE_CBC_SHA { 0x00,0x0A } | 
|  | *      TLS_RSA_WITH_DES_CBC_SHA { 0x00,0x09 } | 
|  | - * The broken server only supports the third and fourth ones and will select | 
|  | - * the third one. | 
|  | + * The broken server only supports the fifth and sixth ones and will select | 
|  | + * the fifth one. | 
|  | */ | 
|  | const PRUint16 SSL_ImplementedCiphers[] = { | 
|  | #ifdef NSS_ENABLE_ECC | 
|  | +    TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, | 
|  | +    TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, | 
|  | TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, | 
|  | TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, | 
|  | /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA must appear before | 
|  | diff -pu a/nss/lib/ssl/sslimpl.h b/nss/lib/ssl/sslimpl.h | 
|  | --- a/nss/lib/ssl/sslimpl.h	2014-01-17 18:03:47.906831535 -0800 | 
|  | +++ b/nss/lib/ssl/sslimpl.h	2014-01-17 18:07:10.270188062 -0800 | 
|  | @@ -65,6 +65,7 @@ typedef SSLSignType     SSL3SignType; | 
|  | #define calg_camellia	ssl_calg_camellia | 
|  | #define calg_seed	ssl_calg_seed | 
|  | #define calg_aes_gcm    ssl_calg_aes_gcm | 
|  | +#define calg_chacha20	ssl_calg_chacha20 | 
|  |  | 
|  | #define mac_null	ssl_mac_null | 
|  | #define mac_md5 	ssl_mac_md5 | 
|  | @@ -299,7 +300,7 @@ typedef struct { | 
|  | } ssl3CipherSuiteCfg; | 
|  |  | 
|  | #ifdef NSS_ENABLE_ECC | 
|  | -#define ssl_V3_SUITES_IMPLEMENTED 61 | 
|  | +#define ssl_V3_SUITES_IMPLEMENTED 63 | 
|  | #else | 
|  | #define ssl_V3_SUITES_IMPLEMENTED 37 | 
|  | #endif /* NSS_ENABLE_ECC */ | 
|  | @@ -483,6 +484,7 @@ typedef enum { | 
|  | cipher_camellia_256, | 
|  | cipher_seed, | 
|  | cipher_aes_128_gcm, | 
|  | +    cipher_chacha20, | 
|  | cipher_missing              /* reserved for no such supported cipher */ | 
|  | /* This enum must match ssl3_cipherName[] in ssl3con.c.  */ | 
|  | } SSL3BulkCipher; | 
|  | diff -pu a/nss/lib/ssl/sslinfo.c b/nss/lib/ssl/sslinfo.c | 
|  | --- a/nss/lib/ssl/sslinfo.c	2014-01-17 18:00:45.503806125 -0800 | 
|  | +++ b/nss/lib/ssl/sslinfo.c	2014-01-17 18:07:10.270188062 -0800 | 
|  | @@ -110,6 +110,7 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLCh | 
|  | #define C_NULL  "NULL", calg_null | 
|  | #define C_SJ 	"SKIPJACK", calg_sj | 
|  | #define C_AESGCM "AES-GCM", calg_aes_gcm | 
|  | +#define C_CHACHA20 "CHACHA20POLY1305", calg_chacha20 | 
|  |  | 
|  | #define B_256	256, 256, 256 | 
|  | #define B_128	128, 128, 128 | 
|  | @@ -188,12 +189,14 @@ static const SSLCipherSuiteInfo suiteInf | 
|  | {0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA),  S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA, 1, 0, 0, }, | 
|  | {0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256), S_ECDSA, K_ECDHE, C_AES, B_128, M_SHA256, 1, 0, 0, }, | 
|  | {0,CS(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA),  S_ECDSA, K_ECDHE, C_AES, B_256, M_SHA, 1, 0, 0, }, | 
|  | +{0,CS(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305),S_ECDSA,K_ECDHE,C_CHACHA20,B_256,M_AEAD_128,0, 0, 0, }, | 
|  |  | 
|  | {0,CS(TLS_ECDH_RSA_WITH_NULL_SHA),            S_RSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0, }, | 
|  | {0,CS(TLS_ECDH_RSA_WITH_RC4_128_SHA),         S_RSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0, }, | 
|  | {0,CS(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA),    S_RSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0, }, | 
|  | {0,CS(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA),     S_RSA, K_ECDH, C_AES, B_128, M_SHA, 1, 0, 0, }, | 
|  | {0,CS(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA),     S_RSA, K_ECDH, C_AES, B_256, M_SHA, 1, 0, 0, }, | 
|  | +{0,CS(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305),  S_RSA,K_ECDHE,C_CHACHA20,B_256,M_AEAD_128, 0, 0, 0, }, | 
|  |  | 
|  | {0,CS(TLS_ECDHE_RSA_WITH_NULL_SHA),           S_RSA, K_ECDHE, C_NULL, B_0, M_SHA, 0, 0, 0, }, | 
|  | {0,CS(TLS_ECDHE_RSA_WITH_RC4_128_SHA),        S_RSA, K_ECDHE, C_RC4, B_128, M_SHA, 0, 0, 0, }, | 
|  | diff -pu a/nss/lib/ssl/sslproto.h b/nss/lib/ssl/sslproto.h | 
|  | --- a/nss/lib/ssl/sslproto.h	2014-01-17 17:49:26.072517368 -0800 | 
|  | +++ b/nss/lib/ssl/sslproto.h	2014-01-17 18:07:10.270188062 -0800 | 
|  | @@ -213,6 +213,9 @@ | 
|  | #define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256   0xC02F | 
|  | #define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256    0xC031 | 
|  |  | 
|  | +#define TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305	0xCC13 | 
|  | +#define TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305	0xCC14 | 
|  | + | 
|  | /* Netscape "experimental" cipher suites. */ | 
|  | #define SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA	0xffe0 | 
|  | #define SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA	0xffe1 | 
|  | diff -pu a/nss/lib/ssl/sslt.h b/nss/lib/ssl/sslt.h | 
|  | --- a/nss/lib/ssl/sslt.h	2014-01-17 18:03:47.906831535 -0800 | 
|  | +++ b/nss/lib/ssl/sslt.h	2014-01-17 18:07:10.270188062 -0800 | 
|  | @@ -94,7 +94,8 @@ typedef enum { | 
|  | ssl_calg_aes      = 7, | 
|  | ssl_calg_camellia = 8, | 
|  | ssl_calg_seed     = 9, | 
|  | -    ssl_calg_aes_gcm  = 10 | 
|  | +    ssl_calg_aes_gcm  = 10, | 
|  | +    ssl_calg_chacha20 = 11 | 
|  | } SSLCipherAlgorithm; | 
|  |  | 
|  | typedef enum { |