Index: net/third_party/nss/patches/chacha20poly1305.patch |
diff --git a/net/third_party/nss/patches/chacha20poly1305.patch b/net/third_party/nss/patches/chacha20poly1305.patch |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ae9882041cdec82d62d3402826faa1ac9ad3e89b |
--- /dev/null |
+++ b/net/third_party/nss/patches/chacha20poly1305.patch |
@@ -0,0 +1,267 @@ |
+diff --git a/nss/lib/ssl/ssl3con.c b/nss/lib/ssl/ssl3con.c |
+index 8be517c..74e9a56 100644 |
+--- a/nss/lib/ssl/ssl3con.c |
++++ b/nss/lib/ssl/ssl3con.c |
+@@ -40,6 +40,20 @@ |
+ #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 + 25) |
++ |
++typedef struct CK_AEAD_PARAMS { |
++ CK_BYTE_PTR pIv; /* This is the nonce. */ |
++ CK_ULONG ulIvLen; |
++ CK_BYTE_PTR pAAD; |
++ CK_ULONG ulAADLen; |
++} CK_AEAD_PARAMS; |
++ |
++#endif |
++ |
+ #include <stdio.h> |
+ #ifdef NSS_ENABLE_ZLIB |
+ #include "zlib.h" |
+@@ -100,6 +114,8 @@ static SECStatus ssl3_AESGCMBypass(ssl3KeyMaterial *keys, PRBool doDecrypt, |
+ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = { |
+ /* cipher_suite policy enabled is_present*/ |
+ #ifdef NSS_ENABLE_ECC |
++ { TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, |
++ { TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, SSL_NOT_ALLOWED, PR_TRUE, PR_FALSE}, |
+ { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, |
+ { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, |
+ #endif /* NSS_ENABLE_ECC */ |
+@@ -273,6 +289,7 @@ static const ssl3BulkCipherDef bulk_cipher_defs[] = { |
+ {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_c20p1305, calg_c20p1305, 32,32, type_aead, 0, 0,16, 0}, |
+ {cipher_missing, calg_null, 0, 0, type_stream, 0, 0, 0, 0}, |
+ }; |
+ |
+@@ -399,6 +416,8 @@ static const ssl3CipherSuiteDef cipher_suite_defs[] = |
+ {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_ECDSA_WITH_CHACHA20_POLY1305, cipher_c20p1305, mac_null, kea_ecdhe_ecdsa}, |
++ {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, cipher_c20p1305, mac_null, kea_ecdhe_rsa}, |
+ |
+ #ifdef NSS_ENABLE_ECC |
+ {TLS_ECDH_ECDSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_ecdsa}, |
+@@ -464,6 +483,7 @@ static const SSLCipher2Mech alg2Mech[] = { |
+ { calg_camellia , CKM_CAMELLIA_CBC }, |
+ { calg_seed , CKM_SEED_CBC }, |
+ { calg_aes_gcm , CKM_AES_GCM }, |
++ { calg_c20p1305 , CKM_NSS_CHACHA20_POLY1305 }, |
+ /* { calg_init , (CK_MECHANISM_TYPE)0x7fffffffL } */ |
+ }; |
+ |
+@@ -2020,6 +2040,45 @@ 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; |
++ static const int tagSize = 16; |
++ unsigned int uOutLen; |
++ CK_AEAD_PARAMS aeadParams; |
++ |
++ memset(¶m, 0, sizeof(param)); |
++ param.len = sizeof(CK_AEAD_PARAMS); |
++ param.data = (unsigned char *) &aeadParams; |
++ memset(&aeadParams, 0, sizeof(CK_AEAD_PARAMS)); |
++ aeadParams.pIv = (unsigned char *) additionalData; |
++ aeadParams.ulIvLen = 8; |
++ aeadParams.pAAD = (unsigned char *) additionalData; |
++ aeadParams.ulAADLen = additionalDataLen; |
++ |
++ 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. |
+@@ -2053,13 +2112,17 @@ ssl3_InitPendingContextsPKCS11(sslSocket *ss) |
+ pwSpec->client.write_mac_context = NULL; |
+ pwSpec->server.write_mac_context = NULL; |
+ |
+- if (calg == calg_aes_gcm) { |
++ if (calg == calg_aes_gcm || calg == calg_c20p1305) { |
+ 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 --git a/nss/lib/ssl/ssl3ecc.c b/nss/lib/ssl/ssl3ecc.c |
+index a3638e7..21a5e05 100644 |
+--- a/nss/lib/ssl/ssl3ecc.c |
++++ b/nss/lib/ssl/ssl3ecc.c |
+@@ -913,6 +913,7 @@ static const ssl3CipherSuite ecdhe_ecdsa_suites[] = { |
+ 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 */ |
+@@ -924,6 +925,7 @@ static const ssl3CipherSuite ecdhe_rsa_suites[] = { |
+ 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 */ |
+@@ -936,6 +938,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, |
+@@ -943,6 +946,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 --git a/nss/lib/ssl/sslenum.c b/nss/lib/ssl/sslenum.c |
+index 597ec07..fc6b854 100644 |
+--- a/nss/lib/ssl/sslenum.c |
++++ b/nss/lib/ssl/sslenum.c |
+@@ -31,6 +31,8 @@ |
+ const PRUint16 SSL_ImplementedCiphers[] = { |
+ /* AES-GCM */ |
+ #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, |
+ #endif /* NSS_ENABLE_ECC */ |
+diff --git a/nss/lib/ssl/sslimpl.h b/nss/lib/ssl/sslimpl.h |
+index 0fe12d0..855c38b 100644 |
+--- a/nss/lib/ssl/sslimpl.h |
++++ b/nss/lib/ssl/sslimpl.h |
+@@ -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_c20p1305 ssl_calg_c20p1305 |
+ |
+ #define mac_null ssl_mac_null |
+ #define mac_md5 ssl_mac_md5 |
+@@ -292,9 +293,9 @@ 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 |
++#define ssl_V3_SUITES_IMPLEMENTED 39 |
+ #endif /* NSS_ENABLE_ECC */ |
+ |
+ #define MAX_DTLS_SRTP_CIPHER_SUITES 4 |
+@@ -474,6 +475,7 @@ typedef enum { |
+ cipher_camellia_256, |
+ cipher_seed, |
+ cipher_aes_128_gcm, |
++ cipher_c20p1305, |
+ cipher_missing /* reserved for no such supported cipher */ |
+ /* This enum must match ssl3_cipherName[] in ssl3con.c. */ |
+ } SSL3BulkCipher; |
+diff --git a/nss/lib/ssl/sslinfo.c b/nss/lib/ssl/sslinfo.c |
+index 9597209..62a177f 100644 |
+--- a/nss/lib/ssl/sslinfo.c |
++++ b/nss/lib/ssl/sslinfo.c |
+@@ -118,6 +118,7 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len) |
+ #define C_NULL "NULL", calg_null |
+ #define C_SJ "SKIPJACK", calg_sj |
+ #define C_AESGCM "AES-GCM", calg_aes_gcm |
++#define C_C20P1305 "CHACHA20POLY1305", calg_c20p1305 |
+ |
+ #define B_256 256, 256, 256 |
+ #define B_128 128, 128, 128 |
+@@ -136,6 +137,8 @@ SSL_GetChannelInfo(PRFileDesc *fd, SSLChannelInfo *info, PRUintn len) |
+ |
+ static const SSLCipherSuiteInfo suiteInfo[] = { |
+ /* <------ Cipher suite --------------------> <auth> <KEA> <bulk cipher> <MAC> <FIPS> */ |
++{0,CS(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305),S_ECDSA,K_ECDHE,C_C20P1305,B_256,M_AEAD_128,$0, 0, 0, }, |
++{0,CS(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305), S_RSA,K_ECDHE,C_C20P1305,B_256,M_AEAD_128, 0, 0, 0, }, |
+ {0,CS(TLS_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_RSA, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, }, |
+ |
+ {0,CS(TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA), S_RSA, K_DHE, C_CAMELLIA, B_256, M_SHA, 0, 0, 0, }, |
+diff --git a/nss/lib/ssl/sslproto.h b/nss/lib/ssl/sslproto.h |
+index 53bba01..ffecd2a 100644 |
+--- a/nss/lib/ssl/sslproto.h |
++++ b/nss/lib/ssl/sslproto.h |
+@@ -165,6 +165,8 @@ |
+ #define TLS_RSA_WITH_AES_128_GCM_SHA256 0x009C |
+ #define TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x009E |
+ #define TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 0x00A2 |
++#define TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 0xCC13 |
++#define TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 0xCC14 |
+ |
+ /* TLS "Signaling Cipher Suite Value" (SCSV). May be requested by client. |
+ * Must NEVER be chosen by server. SSL 3.0 server acknowledges by sending |
+diff --git a/nss/lib/ssl/sslsock.c b/nss/lib/ssl/sslsock.c |
+index c17c7a3..6408dd5 100644 |
+--- a/nss/lib/ssl/sslsock.c |
++++ b/nss/lib/ssl/sslsock.c |
+@@ -110,6 +110,8 @@ static cipherPolicy ssl_ciphers[] = { /* Export France */ |
+ { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
+ { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
+ { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
++ { TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
++ { TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
+ #endif /* NSS_ENABLE_ECC */ |
+ { 0, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED } |
+ }; |
+diff --git a/nss/lib/ssl/sslt.h b/nss/lib/ssl/sslt.h |
+index b03422e..0668f86 100644 |
+--- a/nss/lib/ssl/sslt.h |
++++ b/nss/lib/ssl/sslt.h |
+@@ -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_c20p1305 = 11 |
+ } SSLCipherAlgorithm; |
+ |
+ typedef enum { |