blob: e4c78017d9a11cc488469e85a37c214a0ae4f2de [file] [log] [blame]
diff --git a/lib/ssl/ssl3con.c b/lib/ssl/ssl3con.c
index 299e414..2533679 100644
--- a/lib/ssl/ssl3con.c
+++ b/lib/ssl/ssl3con.c
@@ -43,6 +43,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"
@@ -110,6 +125,8 @@ static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = {
/* cipher_suite policy enabled isPresent */
#ifndef NSS_DISABLE_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_TRUE, PR_FALSE},
{ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_ALLOWED, PR_TRUE, PR_FALSE},
/* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA is out of order to work around
@@ -307,6 +324,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_chacha20, calg_chacha20, 32,32, type_aead, 0, 0,16, 0},
{cipher_missing, calg_null, 0, 0, type_stream, 0, 0, 0, 0},
};
@@ -433,6 +451,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_RSA_WITH_CHACHA20_POLY1305, cipher_chacha20, mac_aead, kea_ecdhe_rsa},
+ {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, cipher_chacha20, mac_aead, kea_ecdhe_ecdsa},
{TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_dhe_dss},
{TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, cipher_aes_128, hmac_sha256, kea_dhe_dss},
@@ -502,6 +522,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 } */
};
@@ -679,6 +700,8 @@ ssl3_CipherSuiteAllowedForVersionRange(
case TLS_RSA_WITH_NULL_SHA256:
return vrange->max == SSL_LIBRARY_VERSION_TLS_1_2;
+ case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305:
+ case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305:
case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
@@ -2093,6 +2116,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, &param,
+ out, &uOutLen, maxout, in, inlen);
+ } else {
+ rv = pk11_encrypt(keys->write_key, CKM_NSS_CHACHA20_POLY1305, &param,
+ 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.
@@ -2126,13 +2189,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_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 --git a/lib/ssl/ssl3ecc.c b/lib/ssl/ssl3ecc.c
index cf8e741..ab5ab14 100644
--- a/lib/ssl/ssl3ecc.c
+++ b/lib/ssl/ssl3ecc.c
@@ -926,6 +926,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 */
@@ -937,6 +938,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 */
@@ -949,6 +951,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,
@@ -956,6 +959,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/lib/ssl/sslenum.c b/lib/ssl/sslenum.c
index f69aed2..b4a8844 100644
--- a/lib/ssl/sslenum.c
+++ b/lib/ssl/sslenum.c
@@ -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[] = {
#ifndef NSS_DISABLE_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 --git a/lib/ssl/sslimpl.h b/lib/ssl/sslimpl.h
index 60dd243..d5f326f 100644
--- a/lib/ssl/sslimpl.h
+++ b/lib/ssl/sslimpl.h
@@ -66,6 +66,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
@@ -301,7 +302,7 @@ typedef struct {
} ssl3CipherSuiteCfg;
#ifndef NSS_DISABLE_ECC
-#define ssl_V3_SUITES_IMPLEMENTED 64
+#define ssl_V3_SUITES_IMPLEMENTED 66
#else
#define ssl_V3_SUITES_IMPLEMENTED 40
#endif /* NSS_DISABLE_ECC */
@@ -495,6 +496,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 --git a/lib/ssl/sslinfo.c b/lib/ssl/sslinfo.c
index 7048eb8..bef3190 100644
--- a/lib/ssl/sslinfo.c
+++ b/lib/ssl/sslinfo.c
@@ -148,6 +148,7 @@ SSL_GetPreliminaryChannelInfo(PRFileDesc *fd,
#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
@@ -229,12 +230,14 @@ static const SSLCipherSuiteInfo suiteInfo[] = {
{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 --git a/lib/ssl/sslproto.h b/lib/ssl/sslproto.h
index 2db47a5..36ae6c9 100644
--- a/lib/ssl/sslproto.h
+++ b/lib/ssl/sslproto.h
@@ -260,6 +260,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 --git a/lib/ssl/sslt.h b/lib/ssl/sslt.h
index 5593579..a2eff62 100644
--- a/lib/ssl/sslt.h
+++ b/lib/ssl/sslt.h
@@ -117,7 +117,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 {