Index: net/third_party/nss/patches/aesgcm.patch |
=================================================================== |
--- net/third_party/nss/patches/aesgcm.patch (revision 242942) |
+++ net/third_party/nss/patches/aesgcm.patch (working copy) |
@@ -1,1363 +0,0 @@ |
-Index: net/third_party/nss/ssl/sslinfo.c |
-=================================================================== |
---- net/third_party/nss/ssl/sslinfo.c (revision 217715) |
-+++ net/third_party/nss/ssl/sslinfo.c (working copy) |
-@@ -109,7 +109,7 @@ |
- #define K_ECDHE "ECDHE", kt_ecdh |
- |
- #define C_SEED "SEED", calg_seed |
--#define C_CAMELLIA "CAMELLIA", calg_camellia |
-+#define C_CAMELLIA "CAMELLIA", calg_camellia |
- #define C_AES "AES", calg_aes |
- #define C_RC4 "RC4", calg_rc4 |
- #define C_RC2 "RC2", calg_rc2 |
-@@ -117,6 +117,7 @@ |
- #define C_3DES "3DES", calg_3des |
- #define C_NULL "NULL", calg_null |
- #define C_SJ "SKIPJACK", calg_sj |
-+#define C_AESGCM "AES-GCM", calg_aes_gcm |
- |
- #define B_256 256, 256, 256 |
- #define B_128 128, 128, 128 |
-@@ -127,12 +128,16 @@ |
- #define B_40 128, 40, 40 |
- #define B_0 0, 0, 0 |
- |
-+#define M_AEAD_128 "AEAD", ssl_mac_aead, 128 |
- #define M_SHA256 "SHA256", ssl_hmac_sha256, 256 |
- #define M_SHA "SHA1", ssl_mac_sha, 160 |
- #define M_MD5 "MD5", ssl_mac_md5, 128 |
-+#define M_NULL "NULL", ssl_mac_null, 0 |
- |
- static const SSLCipherSuiteInfo suiteInfo[] = { |
- /* <------ Cipher suite --------------------> <auth> <KEA> <bulk cipher> <MAC> <FIPS> */ |
-+{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, }, |
- {0,CS(TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, B_256, M_SHA, 0, 0, 0, }, |
- {0,CS(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256), S_RSA, K_DHE, C_AES, B_256, M_SHA256, 1, 0, 0, }, |
-@@ -146,6 +151,7 @@ |
- {0,CS(TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA), S_DSA, K_DHE, C_CAMELLIA, B_128, M_SHA, 0, 0, 0, }, |
- {0,CS(TLS_DHE_DSS_WITH_RC4_128_SHA), S_DSA, K_DHE, C_RC4, B_128, M_SHA, 0, 0, 0, }, |
- {0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256), S_RSA, K_DHE, C_AES, B_128, M_SHA256, 1, 0, 0, }, |
-+{0,CS(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_DHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, }, |
- {0,CS(TLS_DHE_RSA_WITH_AES_128_CBC_SHA), S_RSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0, }, |
- {0,CS(TLS_DHE_DSS_WITH_AES_128_CBC_SHA), S_DSA, K_DHE, C_AES, B_128, M_SHA, 1, 0, 0, }, |
- {0,CS(TLS_RSA_WITH_SEED_CBC_SHA), S_RSA, K_RSA, C_SEED,B_128, M_SHA, 1, 0, 0, }, |
-@@ -175,6 +181,9 @@ |
- |
- #ifdef NSS_ENABLE_ECC |
- /* ECC cipher suites */ |
-+{0,CS(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256), S_RSA, K_ECDHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, }, |
-+{0,CS(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256), S_ECDSA, K_ECDHE, C_AESGCM, B_128, M_AEAD_128, 1, 0, 0, }, |
-+ |
- {0,CS(TLS_ECDH_ECDSA_WITH_NULL_SHA), S_ECDSA, K_ECDH, C_NULL, B_0, M_SHA, 0, 0, 0, }, |
- {0,CS(TLS_ECDH_ECDSA_WITH_RC4_128_SHA), S_ECDSA, K_ECDH, C_RC4, B_128, M_SHA, 0, 0, 0, }, |
- {0,CS(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA), S_ECDSA, K_ECDH, C_3DES, B_3DES, M_SHA, 1, 0, 0, }, |
-Index: net/third_party/nss/ssl/sslimpl.h |
-=================================================================== |
---- net/third_party/nss/ssl/sslimpl.h (revision 217715) |
-+++ net/third_party/nss/ssl/sslimpl.h (working copy) |
-@@ -64,6 +64,7 @@ |
- #define calg_aes ssl_calg_aes |
- #define calg_camellia ssl_calg_camellia |
- #define calg_seed ssl_calg_seed |
-+#define calg_aes_gcm ssl_calg_aes_gcm |
- |
- #define mac_null ssl_mac_null |
- #define mac_md5 ssl_mac_md5 |
-@@ -71,6 +72,7 @@ |
- #define hmac_md5 ssl_hmac_md5 |
- #define hmac_sha ssl_hmac_sha |
- #define hmac_sha256 ssl_hmac_sha256 |
-+#define mac_aead ssl_mac_aead |
- |
- #define SET_ERROR_CODE /* reminder */ |
- #define SEND_ALERT /* reminder */ |
-@@ -290,9 +292,9 @@ |
- } ssl3CipherSuiteCfg; |
- |
- #ifdef NSS_ENABLE_ECC |
--#define ssl_V3_SUITES_IMPLEMENTED 57 |
-+#define ssl_V3_SUITES_IMPLEMENTED 61 |
- #else |
--#define ssl_V3_SUITES_IMPLEMENTED 35 |
-+#define ssl_V3_SUITES_IMPLEMENTED 37 |
- #endif /* NSS_ENABLE_ECC */ |
- |
- #define MAX_DTLS_SRTP_CIPHER_SUITES 4 |
-@@ -440,20 +442,6 @@ |
- #define GS_DATA 3 |
- #define GS_PAD 4 |
- |
--typedef SECStatus (*SSLCipher)(void * context, |
-- unsigned char * out, |
-- int * outlen, |
-- int maxout, |
-- const unsigned char *in, |
-- int inlen); |
--typedef SECStatus (*SSLCompressor)(void * context, |
-- unsigned char * out, |
-- int * outlen, |
-- int maxout, |
-- const unsigned char *in, |
-- int inlen); |
--typedef SECStatus (*SSLDestroy)(void *context, PRBool freeit); |
-- |
- #if defined(NSS_PLATFORM_CLIENT_AUTH) && defined(XP_WIN32) |
- typedef PCERT_KEY_CONTEXT PlatformKey; |
- #elif defined(NSS_PLATFORM_CLIENT_AUTH) && defined(XP_MACOSX) |
-@@ -485,11 +473,12 @@ |
- cipher_camellia_128, |
- cipher_camellia_256, |
- cipher_seed, |
-+ cipher_aes_128_gcm, |
- cipher_missing /* reserved for no such supported cipher */ |
- /* This enum must match ssl3_cipherName[] in ssl3con.c. */ |
- } SSL3BulkCipher; |
- |
--typedef enum { type_stream, type_block } CipherType; |
-+typedef enum { type_stream, type_block, type_aead } CipherType; |
- |
- #define MAX_IV_LENGTH 24 |
- |
-@@ -531,6 +520,30 @@ |
- PRUint64 cipher_context[MAX_CIPHER_CONTEXT_LLONGS]; |
- } ssl3KeyMaterial; |
- |
-+typedef SECStatus (*SSLCipher)(void * context, |
-+ unsigned char * out, |
-+ int * outlen, |
-+ int maxout, |
-+ const unsigned char *in, |
-+ int inlen); |
-+typedef SECStatus (*SSLAEADCipher)( |
-+ ssl3KeyMaterial * keys, |
-+ PRBool doDecrypt, |
-+ unsigned char * out, |
-+ int * outlen, |
-+ int maxout, |
-+ const unsigned char *in, |
-+ int inlen, |
-+ const unsigned char *additionalData, |
-+ int additionalDataLen); |
-+typedef SECStatus (*SSLCompressor)(void * context, |
-+ unsigned char * out, |
-+ int * outlen, |
-+ int maxout, |
-+ const unsigned char *in, |
-+ int inlen); |
-+typedef SECStatus (*SSLDestroy)(void *context, PRBool freeit); |
-+ |
- /* The DTLS anti-replay window. Defined here because we need it in |
- * the cipher spec. Note that this is a ring buffer but left and |
- * right represent the true window, with modular arithmetic used to |
-@@ -557,6 +570,7 @@ |
- int mac_size; |
- SSLCipher encode; |
- SSLCipher decode; |
-+ SSLAEADCipher aead; |
- SSLDestroy destroy; |
- void * encodeContext; |
- void * decodeContext; |
-@@ -706,8 +720,6 @@ |
- PRBool tls_keygen; |
- } ssl3KEADef; |
- |
--typedef enum { kg_null, kg_strong, kg_export } SSL3KeyGenMode; |
-- |
- /* |
- ** There are tables of these, all const. |
- */ |
-@@ -719,7 +731,8 @@ |
- CipherType type; |
- int iv_size; |
- int block_size; |
-- SSL3KeyGenMode keygen_mode; |
-+ int tag_size; /* authentication tag size for AEAD ciphers. */ |
-+ int explicit_nonce_size; /* for AEAD ciphers. */ |
- }; |
- |
- /* |
-Index: net/third_party/nss/ssl/ssl3ecc.c |
-=================================================================== |
---- net/third_party/nss/ssl/ssl3ecc.c (revision 217715) |
-+++ net/third_party/nss/ssl/ssl3ecc.c (working copy) |
-@@ -911,6 +911,7 @@ |
- TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, |
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, |
- 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_NULL_SHA, |
- TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, |
-@@ -921,6 +922,7 @@ |
- TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, |
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, |
- 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_NULL_SHA, |
- TLS_ECDHE_RSA_WITH_RC4_128_SHA, |
-@@ -932,12 +934,14 @@ |
- TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, |
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, |
- 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_NULL_SHA, |
- TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, |
- TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, |
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, |
- 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_NULL_SHA, |
- TLS_ECDHE_RSA_WITH_RC4_128_SHA, |
-Index: net/third_party/nss/ssl/sslsock.c |
-=================================================================== |
---- net/third_party/nss/ssl/sslsock.c (revision 217715) |
-+++ net/third_party/nss/ssl/sslsock.c (working copy) |
-@@ -67,8 +67,10 @@ |
- { TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
- { TLS_DHE_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
- { TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
-+ { TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
- { TLS_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
- { TLS_RSA_WITH_AES_128_CBC_SHA256, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
-+ { TLS_RSA_WITH_AES_128_GCM_SHA256, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
- { TLS_DHE_DSS_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
- { TLS_DHE_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
- { TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
-@@ -94,6 +96,7 @@ |
- { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
- { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
- { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
-+ { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
- { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
- { TLS_ECDH_RSA_WITH_NULL_SHA, SSL_ALLOWED, SSL_ALLOWED }, |
- { TLS_ECDH_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
-@@ -105,6 +108,7 @@ |
- { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
- { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED }, |
- { 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 }, |
- #endif /* NSS_ENABLE_ECC */ |
- { 0, SSL_NOT_ALLOWED, SSL_NOT_ALLOWED } |
-Index: net/third_party/nss/ssl/ssl3con.c |
-=================================================================== |
---- net/third_party/nss/ssl/ssl3con.c (revision 217715) |
-+++ net/third_party/nss/ssl/ssl3con.c (working copy) |
-@@ -78,6 +78,13 @@ |
- static SECStatus Null_Cipher(void *ctx, unsigned char *output, int *outputLen, |
- int maxOutputLen, const unsigned char *input, |
- int inputLen); |
-+#ifndef NO_PKCS11_BYPASS |
-+static SECStatus ssl3_AESGCMBypass(ssl3KeyMaterial *keys, PRBool doDecrypt, |
-+ unsigned char *out, int *outlen, int maxout, |
-+ const unsigned char *in, int inlen, |
-+ const unsigned char *additionalData, |
-+ int additionalDataLen); |
-+#endif |
- |
- #define MAX_SEND_BUF_LENGTH 32000 /* watch for 16-bit integer overflow */ |
- #define MIN_SEND_BUF_LENGTH 4000 |
-@@ -90,6 +97,13 @@ |
- static ssl3CipherSuiteCfg cipherSuites[ssl_V3_SUITES_IMPLEMENTED] = { |
- /* cipher_suite policy enabled is_present*/ |
- #ifdef NSS_ENABLE_ECC |
-+ { 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 */ |
-+ { TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE}, |
-+ { TLS_RSA_WITH_AES_128_GCM_SHA256, SSL_NOT_ALLOWED, PR_TRUE,PR_FALSE}, |
-+ |
-+#ifdef NSS_ENABLE_ECC |
- { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, |
- { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, SSL_NOT_ALLOWED, PR_FALSE,PR_FALSE}, |
- #endif /* NSS_ENABLE_ECC */ |
-@@ -233,23 +247,30 @@ |
- |
- /* indexed by SSL3BulkCipher */ |
- static const ssl3BulkCipherDef bulk_cipher_defs[] = { |
-- /* cipher calg keySz secretSz type ivSz BlkSz keygen */ |
-- {cipher_null, calg_null, 0, 0, type_stream, 0, 0, kg_null}, |
-- {cipher_rc4, calg_rc4, 16, 16, type_stream, 0, 0, kg_strong}, |
-- {cipher_rc4_40, calg_rc4, 16, 5, type_stream, 0, 0, kg_export}, |
-- {cipher_rc4_56, calg_rc4, 16, 7, type_stream, 0, 0, kg_export}, |
-- {cipher_rc2, calg_rc2, 16, 16, type_block, 8, 8, kg_strong}, |
-- {cipher_rc2_40, calg_rc2, 16, 5, type_block, 8, 8, kg_export}, |
-- {cipher_des, calg_des, 8, 8, type_block, 8, 8, kg_strong}, |
-- {cipher_3des, calg_3des, 24, 24, type_block, 8, 8, kg_strong}, |
-- {cipher_des40, calg_des, 8, 5, type_block, 8, 8, kg_export}, |
-- {cipher_idea, calg_idea, 16, 16, type_block, 8, 8, kg_strong}, |
-- {cipher_aes_128, calg_aes, 16, 16, type_block, 16,16, kg_strong}, |
-- {cipher_aes_256, calg_aes, 32, 32, type_block, 16,16, kg_strong}, |
-- {cipher_camellia_128, calg_camellia,16, 16, type_block, 16,16, kg_strong}, |
-- {cipher_camellia_256, calg_camellia,32, 32, type_block, 16,16, kg_strong}, |
-- {cipher_seed, calg_seed, 16, 16, type_block, 16,16, kg_strong}, |
-- {cipher_missing, calg_null, 0, 0, type_stream, 0, 0, kg_null}, |
-+ /* |--------- Lengths --------| */ |
-+ /* cipher calg k s type i b t n */ |
-+ /* e e v l a o */ |
-+ /* y c | o g n */ |
-+ /* | r | c | c */ |
-+ /* | e | k | e */ |
-+ /* | t | | | | */ |
-+ {cipher_null, calg_null, 0, 0, type_stream, 0, 0, 0, 0}, |
-+ {cipher_rc4, calg_rc4, 16,16, type_stream, 0, 0, 0, 0}, |
-+ {cipher_rc4_40, calg_rc4, 16, 5, type_stream, 0, 0, 0, 0}, |
-+ {cipher_rc4_56, calg_rc4, 16, 7, type_stream, 0, 0, 0, 0}, |
-+ {cipher_rc2, calg_rc2, 16,16, type_block, 8, 8, 0, 0}, |
-+ {cipher_rc2_40, calg_rc2, 16, 5, type_block, 8, 8, 0, 0}, |
-+ {cipher_des, calg_des, 8, 8, type_block, 8, 8, 0, 0}, |
-+ {cipher_3des, calg_3des, 24,24, type_block, 8, 8, 0, 0}, |
-+ {cipher_des40, calg_des, 8, 5, type_block, 8, 8, 0, 0}, |
-+ {cipher_idea, calg_idea, 16,16, type_block, 8, 8, 0, 0}, |
-+ {cipher_aes_128, calg_aes, 16,16, type_block, 16,16, 0, 0}, |
-+ {cipher_aes_256, calg_aes, 32,32, type_block, 16,16, 0, 0}, |
-+ {cipher_camellia_128, calg_camellia, 16,16, type_block, 16,16, 0, 0}, |
-+ {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_missing, calg_null, 0, 0, type_stream, 0, 0, 0, 0}, |
- }; |
- |
- static const ssl3KEADef kea_defs[] = |
-@@ -371,6 +392,11 @@ |
- {SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, cipher_3des, mac_sha, kea_rsa_fips}, |
- {SSL_RSA_FIPS_WITH_DES_CBC_SHA, cipher_des, mac_sha, kea_rsa_fips}, |
- |
-+ {TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, cipher_aes_128_gcm, mac_aead, kea_dhe_rsa}, |
-+ {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}, |
-+ |
- #ifdef NSS_ENABLE_ECC |
- {TLS_ECDH_ECDSA_WITH_NULL_SHA, cipher_null, mac_sha, kea_ecdh_ecdsa}, |
- {TLS_ECDH_ECDSA_WITH_RC4_128_SHA, cipher_rc4, mac_sha, kea_ecdh_ecdsa}, |
-@@ -434,25 +460,29 @@ |
- { calg_aes , CKM_AES_CBC }, |
- { calg_camellia , CKM_CAMELLIA_CBC }, |
- { calg_seed , CKM_SEED_CBC }, |
-+ { calg_aes_gcm , CKM_AES_GCM }, |
- /* { calg_init , (CK_MECHANISM_TYPE)0x7fffffffL } */ |
- }; |
- |
--#define mmech_null (CK_MECHANISM_TYPE)0x80000000L |
-+#define mmech_invalid (CK_MECHANISM_TYPE)0x80000000L |
- #define mmech_md5 CKM_SSL3_MD5_MAC |
- #define mmech_sha CKM_SSL3_SHA1_MAC |
- #define mmech_md5_hmac CKM_MD5_HMAC |
- #define mmech_sha_hmac CKM_SHA_1_HMAC |
- #define mmech_sha256_hmac CKM_SHA256_HMAC |
-+#define mmech_sha384_hmac CKM_SHA384_HMAC |
-+#define mmech_sha512_hmac CKM_SHA512_HMAC |
- |
- static const ssl3MACDef mac_defs[] = { /* indexed by SSL3MACAlgorithm */ |
- /* pad_size is only used for SSL 3.0 MAC. See RFC 6101 Sec. 5.2.3.1. */ |
- /* mac mmech pad_size mac_size */ |
-- { mac_null, mmech_null, 0, 0 }, |
-+ { mac_null, mmech_invalid, 0, 0 }, |
- { mac_md5, mmech_md5, 48, MD5_LENGTH }, |
- { mac_sha, mmech_sha, 40, SHA1_LENGTH}, |
- {hmac_md5, mmech_md5_hmac, 0, MD5_LENGTH }, |
- {hmac_sha, mmech_sha_hmac, 0, SHA1_LENGTH}, |
- {hmac_sha256, mmech_sha256_hmac, 0, SHA256_LENGTH}, |
-+ { mac_aead, mmech_invalid, 0, 0 }, |
- }; |
- |
- /* indexed by SSL3BulkCipher */ |
-@@ -472,6 +502,7 @@ |
- "Camellia-128", |
- "Camellia-256", |
- "SEED-CBC", |
-+ "AES-128-GCM", |
- "missing" |
- }; |
- |
-@@ -598,9 +629,13 @@ |
- 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: |
-+ case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: |
- case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: |
-+ case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: |
- case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: |
-+ case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: |
- case TLS_RSA_WITH_AES_128_CBC_SHA256: |
-+ case TLS_RSA_WITH_AES_128_GCM_SHA256: |
- case TLS_RSA_WITH_NULL_SHA256: |
- return version >= SSL_LIBRARY_VERSION_TLS_1_2; |
- default: |
-@@ -1360,7 +1395,7 @@ |
- cipher = suite_def->bulk_cipher_alg; |
- kea = suite_def->key_exchange_alg; |
- mac = suite_def->mac_alg; |
-- if (mac <= ssl_mac_sha && isTLS) |
-+ if (mac <= ssl_mac_sha && mac != ssl_mac_null && isTLS) |
- mac += 2; |
- |
- ss->ssl3.hs.suite_def = suite_def; |
-@@ -1554,7 +1589,6 @@ |
- unsigned int optArg2 = 0; |
- PRBool server_encrypts = ss->sec.isServer; |
- SSLCipherAlgorithm calg; |
-- SSLCompressionMethod compression_method; |
- SECStatus rv; |
- |
- PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
-@@ -1565,8 +1599,18 @@ |
- cipher_def = pwSpec->cipher_def; |
- |
- calg = cipher_def->calg; |
-- compression_method = pwSpec->compression_method; |
- |
-+ if (calg == calg_aes_gcm) { |
-+ pwSpec->encode = NULL; |
-+ pwSpec->decode = NULL; |
-+ pwSpec->destroy = NULL; |
-+ pwSpec->encodeContext = NULL; |
-+ pwSpec->decodeContext = NULL; |
-+ pwSpec->aead = ssl3_AESGCMBypass; |
-+ ssl3_InitCompressionContext(pwSpec); |
-+ return SECSuccess; |
-+ } |
-+ |
- serverContext = pwSpec->server.cipher_context; |
- clientContext = pwSpec->client.cipher_context; |
- |
-@@ -1721,6 +1765,195 @@ |
- return param; |
- } |
- |
-+/* ssl3_BuildRecordPseudoHeader writes the SSL/TLS pseudo-header (the data |
-+ * which is included in the MAC or AEAD additional data) to |out| and returns |
-+ * its length. See https://tools.ietf.org/html/rfc5246#section-6.2.3.3 for the |
-+ * definition of the AEAD additional data. |
-+ * |
-+ * TLS pseudo-header includes the record's version field, SSL's doesn't. Which |
-+ * pseudo-header defintiion to use should be decided based on the version of |
-+ * the protocol that was negotiated when the cipher spec became current, NOT |
-+ * based on the version value in the record itself, and the decision is passed |
-+ * to this function as the |includesVersion| argument. But, the |version| |
-+ * argument should be the record's version value. |
-+ */ |
-+static unsigned int |
-+ssl3_BuildRecordPseudoHeader(unsigned char *out, |
-+ SSL3SequenceNumber seq_num, |
-+ SSL3ContentType type, |
-+ PRBool includesVersion, |
-+ SSL3ProtocolVersion version, |
-+ PRBool isDTLS, |
-+ int length) |
-+{ |
-+ out[0] = (unsigned char)(seq_num.high >> 24); |
-+ out[1] = (unsigned char)(seq_num.high >> 16); |
-+ out[2] = (unsigned char)(seq_num.high >> 8); |
-+ out[3] = (unsigned char)(seq_num.high >> 0); |
-+ out[4] = (unsigned char)(seq_num.low >> 24); |
-+ out[5] = (unsigned char)(seq_num.low >> 16); |
-+ out[6] = (unsigned char)(seq_num.low >> 8); |
-+ out[7] = (unsigned char)(seq_num.low >> 0); |
-+ out[8] = type; |
-+ |
-+ /* SSL3 MAC doesn't include the record's version field. */ |
-+ if (!includesVersion) { |
-+ out[9] = MSB(length); |
-+ out[10] = LSB(length); |
-+ return 11; |
-+ } |
-+ |
-+ /* TLS MAC and AEAD additional data include version. */ |
-+ if (isDTLS) { |
-+ SSL3ProtocolVersion dtls_version; |
-+ |
-+ dtls_version = dtls_TLSVersionToDTLSVersion(version); |
-+ out[9] = MSB(dtls_version); |
-+ out[10] = LSB(dtls_version); |
-+ } else { |
-+ out[9] = MSB(version); |
-+ out[10] = LSB(version); |
-+ } |
-+ out[11] = MSB(length); |
-+ out[12] = LSB(length); |
-+ return 13; |
-+} |
-+ |
-+static SECStatus |
-+ssl3_AESGCM(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 char nonce[12]; |
-+ unsigned int uOutLen; |
-+ CK_GCM_PARAMS gcmParams; |
-+ |
-+ static const int tagSize = 16; |
-+ static const int explicitNonceLen = 8; |
-+ |
-+ /* See https://tools.ietf.org/html/rfc5288#section-3 for details of how the |
-+ * nonce is formed. */ |
-+ memcpy(nonce, keys->write_iv, 4); |
-+ if (doDecrypt) { |
-+ memcpy(nonce + 4, in, explicitNonceLen); |
-+ in += explicitNonceLen; |
-+ inlen -= explicitNonceLen; |
-+ *outlen = 0; |
-+ } else { |
-+ if (maxout < explicitNonceLen) { |
-+ PORT_SetError(SEC_ERROR_INPUT_LEN); |
-+ return SECFailure; |
-+ } |
-+ /* Use the 64-bit sequence number as the explicit nonce. */ |
-+ memcpy(nonce + 4, additionalData, explicitNonceLen); |
-+ memcpy(out, additionalData, explicitNonceLen); |
-+ out += explicitNonceLen; |
-+ maxout -= explicitNonceLen; |
-+ *outlen = explicitNonceLen; |
-+ } |
-+ |
-+ param.type = siBuffer; |
-+ param.data = (unsigned char *) &gcmParams; |
-+ param.len = sizeof(gcmParams); |
-+ gcmParams.pIv = nonce; |
-+ gcmParams.ulIvLen = sizeof(nonce); |
-+ gcmParams.pAAD = (unsigned char *)additionalData; /* const cast */ |
-+ gcmParams.ulAADLen = additionalDataLen; |
-+ gcmParams.ulTagBits = tagSize * 8; |
-+ |
-+ if (doDecrypt) { |
-+ rv = PK11_Decrypt(keys->write_key, CKM_AES_GCM, ¶m, out, &uOutLen, |
-+ maxout, in, inlen); |
-+ } else { |
-+ rv = PK11_Encrypt(keys->write_key, CKM_AES_GCM, ¶m, out, &uOutLen, |
-+ maxout, in, inlen); |
-+ } |
-+ *outlen += (int) uOutLen; |
-+ |
-+ return rv; |
-+} |
-+ |
-+#ifndef NO_PKCS11_BYPASS |
-+static SECStatus |
-+ssl3_AESGCMBypass(ssl3KeyMaterial *keys, |
-+ PRBool doDecrypt, |
-+ unsigned char *out, |
-+ int *outlen, |
-+ int maxout, |
-+ const unsigned char *in, |
-+ int inlen, |
-+ const unsigned char *additionalData, |
-+ int additionalDataLen) |
-+{ |
-+ SECStatus rv = SECFailure; |
-+ unsigned char nonce[12]; |
-+ unsigned int uOutLen; |
-+ AESContext *cx; |
-+ CK_GCM_PARAMS gcmParams; |
-+ |
-+ static const int tagSize = 16; |
-+ static const int explicitNonceLen = 8; |
-+ |
-+ /* See https://tools.ietf.org/html/rfc5288#section-3 for details of how the |
-+ * nonce is formed. */ |
-+ PORT_Assert(keys->write_iv_item.len == 4); |
-+ if (keys->write_iv_item.len != 4) { |
-+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
-+ return SECFailure; |
-+ } |
-+ memcpy(nonce, keys->write_iv_item.data, 4); |
-+ if (doDecrypt) { |
-+ memcpy(nonce + 4, in, explicitNonceLen); |
-+ in += explicitNonceLen; |
-+ inlen -= explicitNonceLen; |
-+ *outlen = 0; |
-+ } else { |
-+ if (maxout < explicitNonceLen) { |
-+ PORT_SetError(SEC_ERROR_INPUT_LEN); |
-+ return SECFailure; |
-+ } |
-+ /* Use the 64-bit sequence number as the explicit nonce. */ |
-+ memcpy(nonce + 4, additionalData, explicitNonceLen); |
-+ memcpy(out, additionalData, explicitNonceLen); |
-+ out += explicitNonceLen; |
-+ maxout -= explicitNonceLen; |
-+ *outlen = explicitNonceLen; |
-+ } |
-+ |
-+ gcmParams.pIv = nonce; |
-+ gcmParams.ulIvLen = sizeof(nonce); |
-+ gcmParams.pAAD = (unsigned char *)additionalData; /* const cast */ |
-+ gcmParams.ulAADLen = additionalDataLen; |
-+ gcmParams.ulTagBits = tagSize * 8; |
-+ |
-+ cx = (AESContext *)keys->cipher_context; |
-+ rv = AES_InitContext(cx, keys->write_key_item.data, |
-+ keys->write_key_item.len, |
-+ (unsigned char *)&gcmParams, NSS_AES_GCM, !doDecrypt, |
-+ AES_BLOCK_SIZE); |
-+ if (rv != SECSuccess) { |
-+ return rv; |
-+ } |
-+ if (doDecrypt) { |
-+ rv = AES_Decrypt(cx, out, &uOutLen, maxout, in, inlen); |
-+ } else { |
-+ rv = AES_Encrypt(cx, out, &uOutLen, maxout, in, inlen); |
-+ } |
-+ AES_DestroyContext(cx, PR_FALSE); |
-+ *outlen += (int) uOutLen; |
-+ |
-+ return rv; |
-+} |
-+#endif |
-+ |
- /* Initialize encryption and MAC contexts for pending spec. |
- * Master Secret already is derived. |
- * Caller holds Spec write lock. |
-@@ -1748,14 +1981,27 @@ |
- pwSpec = ss->ssl3.pwSpec; |
- cipher_def = pwSpec->cipher_def; |
- macLength = pwSpec->mac_size; |
-+ calg = cipher_def->calg; |
-+ PORT_Assert(alg2Mech[calg].calg == calg); |
- |
-+ pwSpec->client.write_mac_context = NULL; |
-+ pwSpec->server.write_mac_context = NULL; |
-+ |
-+ if (calg == calg_aes_gcm) { |
-+ pwSpec->encode = NULL; |
-+ pwSpec->decode = NULL; |
-+ pwSpec->destroy = NULL; |
-+ pwSpec->encodeContext = NULL; |
-+ pwSpec->decodeContext = NULL; |
-+ pwSpec->aead = ssl3_AESGCM; |
-+ return SECSuccess; |
-+ } |
-+ |
- /* |
- ** Now setup the MAC contexts, |
- ** crypto contexts are setup below. |
- */ |
- |
-- pwSpec->client.write_mac_context = NULL; |
-- pwSpec->server.write_mac_context = NULL; |
- mac_mech = pwSpec->mac_def->mmech; |
- mac_param.data = (unsigned char *)&macLength; |
- mac_param.len = sizeof(macLength); |
-@@ -1778,9 +2024,6 @@ |
- ** Now setup the crypto contexts. |
- */ |
- |
-- calg = cipher_def->calg; |
-- PORT_Assert(alg2Mech[calg].calg == calg); |
-- |
- if (calg == calg_null) { |
- pwSpec->encode = Null_Cipher; |
- pwSpec->decode = Null_Cipher; |
-@@ -1988,10 +2231,8 @@ |
- ssl3_ComputeRecordMAC( |
- ssl3CipherSpec * spec, |
- PRBool useServerMacKey, |
-- PRBool isDTLS, |
-- SSL3ContentType type, |
-- SSL3ProtocolVersion version, |
-- SSL3SequenceNumber seq_num, |
-+ const unsigned char *header, |
-+ unsigned int headerLen, |
- const SSL3Opaque * input, |
- int inputLength, |
- unsigned char * outbuf, |
-@@ -1999,56 +2240,8 @@ |
- { |
- const ssl3MACDef * mac_def; |
- SECStatus rv; |
--#ifndef NO_PKCS11_BYPASS |
-- PRBool isTLS; |
--#endif |
-- unsigned int tempLen; |
-- unsigned char temp[MAX_MAC_LENGTH]; |
- |
-- temp[0] = (unsigned char)(seq_num.high >> 24); |
-- temp[1] = (unsigned char)(seq_num.high >> 16); |
-- temp[2] = (unsigned char)(seq_num.high >> 8); |
-- temp[3] = (unsigned char)(seq_num.high >> 0); |
-- temp[4] = (unsigned char)(seq_num.low >> 24); |
-- temp[5] = (unsigned char)(seq_num.low >> 16); |
-- temp[6] = (unsigned char)(seq_num.low >> 8); |
-- temp[7] = (unsigned char)(seq_num.low >> 0); |
-- temp[8] = type; |
-- |
-- /* TLS MAC includes the record's version field, SSL's doesn't. |
-- ** We decide which MAC defintiion to use based on the version of |
-- ** the protocol that was negotiated when the spec became current, |
-- ** NOT based on the version value in the record itself. |
-- ** But, we use the record'v version value in the computation. |
-- */ |
-- if (spec->version <= SSL_LIBRARY_VERSION_3_0) { |
-- temp[9] = MSB(inputLength); |
-- temp[10] = LSB(inputLength); |
-- tempLen = 11; |
--#ifndef NO_PKCS11_BYPASS |
-- isTLS = PR_FALSE; |
--#endif |
-- } else { |
-- /* New TLS hash includes version. */ |
-- if (isDTLS) { |
-- SSL3ProtocolVersion dtls_version; |
-- |
-- dtls_version = dtls_TLSVersionToDTLSVersion(version); |
-- temp[9] = MSB(dtls_version); |
-- temp[10] = LSB(dtls_version); |
-- } else { |
-- temp[9] = MSB(version); |
-- temp[10] = LSB(version); |
-- } |
-- temp[11] = MSB(inputLength); |
-- temp[12] = LSB(inputLength); |
-- tempLen = 13; |
--#ifndef NO_PKCS11_BYPASS |
-- isTLS = PR_TRUE; |
--#endif |
-- } |
-- |
-- PRINT_BUF(95, (NULL, "frag hash1: temp", temp, tempLen)); |
-+ PRINT_BUF(95, (NULL, "frag hash1: header", header, headerLen)); |
- PRINT_BUF(95, (NULL, "frag hash1: input", input, inputLength)); |
- |
- mac_def = spec->mac_def; |
-@@ -2093,7 +2286,10 @@ |
- return SECFailure; |
- } |
- |
-- if (!isTLS) { |
-+ if (spec->version <= SSL_LIBRARY_VERSION_3_0) { |
-+ unsigned int tempLen; |
-+ unsigned char temp[MAX_MAC_LENGTH]; |
-+ |
- /* compute "inner" part of SSL3 MAC */ |
- hashObj->begin(write_mac_context); |
- if (useServerMacKey) |
-@@ -2105,7 +2301,7 @@ |
- spec->client.write_mac_key_item.data, |
- spec->client.write_mac_key_item.len); |
- hashObj->update(write_mac_context, mac_pad_1, pad_bytes); |
-- hashObj->update(write_mac_context, temp, tempLen); |
-+ hashObj->update(write_mac_context, header, headerLen); |
- hashObj->update(write_mac_context, input, inputLength); |
- hashObj->end(write_mac_context, temp, &tempLen, sizeof temp); |
- |
-@@ -2136,7 +2332,7 @@ |
- } |
- if (rv == SECSuccess) { |
- HMAC_Begin(cx); |
-- HMAC_Update(cx, temp, tempLen); |
-+ HMAC_Update(cx, header, headerLen); |
- HMAC_Update(cx, input, inputLength); |
- rv = HMAC_Finish(cx, outbuf, outLength, spec->mac_size); |
- HMAC_Destroy(cx, PR_FALSE); |
-@@ -2150,7 +2346,7 @@ |
- (useServerMacKey ? spec->server.write_mac_context |
- : spec->client.write_mac_context); |
- rv = PK11_DigestBegin(mac_context); |
-- rv |= PK11_DigestOp(mac_context, temp, tempLen); |
-+ rv |= PK11_DigestOp(mac_context, header, headerLen); |
- rv |= PK11_DigestOp(mac_context, input, inputLength); |
- rv |= PK11_DigestFinal(mac_context, outbuf, outLength, spec->mac_size); |
- } |
-@@ -2190,10 +2386,8 @@ |
- ssl3_ComputeRecordMACConstantTime( |
- ssl3CipherSpec * spec, |
- PRBool useServerMacKey, |
-- PRBool isDTLS, |
-- SSL3ContentType type, |
-- SSL3ProtocolVersion version, |
-- SSL3SequenceNumber seq_num, |
-+ const unsigned char *header, |
-+ unsigned int headerLen, |
- const SSL3Opaque * input, |
- int inputLen, |
- int originalLen, |
-@@ -2205,9 +2399,7 @@ |
- PK11Context * mac_context; |
- SECItem param; |
- SECStatus rv; |
-- unsigned char header[13]; |
- PK11SymKey * key; |
-- int recordLength; |
- |
- PORT_Assert(inputLen >= spec->mac_size); |
- PORT_Assert(originalLen >= inputLen); |
-@@ -2223,42 +2415,15 @@ |
- return SECSuccess; |
- } |
- |
-- header[0] = (unsigned char)(seq_num.high >> 24); |
-- header[1] = (unsigned char)(seq_num.high >> 16); |
-- header[2] = (unsigned char)(seq_num.high >> 8); |
-- header[3] = (unsigned char)(seq_num.high >> 0); |
-- header[4] = (unsigned char)(seq_num.low >> 24); |
-- header[5] = (unsigned char)(seq_num.low >> 16); |
-- header[6] = (unsigned char)(seq_num.low >> 8); |
-- header[7] = (unsigned char)(seq_num.low >> 0); |
-- header[8] = type; |
-- |
- macType = CKM_NSS_HMAC_CONSTANT_TIME; |
-- recordLength = inputLen - spec->mac_size; |
- if (spec->version <= SSL_LIBRARY_VERSION_3_0) { |
- macType = CKM_NSS_SSL3_MAC_CONSTANT_TIME; |
-- header[9] = recordLength >> 8; |
-- header[10] = recordLength; |
-- params.ulHeaderLen = 11; |
-- } else { |
-- if (isDTLS) { |
-- SSL3ProtocolVersion dtls_version; |
-- |
-- dtls_version = dtls_TLSVersionToDTLSVersion(version); |
-- header[9] = dtls_version >> 8; |
-- header[10] = dtls_version; |
-- } else { |
-- header[9] = version >> 8; |
-- header[10] = version; |
-- } |
-- header[11] = recordLength >> 8; |
-- header[12] = recordLength; |
-- params.ulHeaderLen = 13; |
- } |
- |
- params.macAlg = spec->mac_def->mmech; |
- params.ulBodyTotalLen = originalLen; |
-- params.pHeader = header; |
-+ params.pHeader = (unsigned char *) header; /* const cast */ |
-+ params.ulHeaderLen = headerLen; |
- |
- param.data = (unsigned char*) ¶ms; |
- param.len = sizeof(params); |
-@@ -2291,9 +2456,8 @@ |
- /* ssl3_ComputeRecordMAC expects the MAC to have been removed from the |
- * length already. */ |
- inputLen -= spec->mac_size; |
-- return ssl3_ComputeRecordMAC(spec, useServerMacKey, isDTLS, type, |
-- version, seq_num, input, inputLen, |
-- outbuf, outLen); |
-+ return ssl3_ComputeRecordMAC(spec, useServerMacKey, header, headerLen, |
-+ input, inputLen, outbuf, outLen); |
- } |
- |
- static PRBool |
-@@ -2345,6 +2509,8 @@ |
- PRUint16 headerLen; |
- int ivLen = 0; |
- int cipherBytes = 0; |
-+ unsigned char pseudoHeader[13]; |
-+ unsigned int pseudoHeaderLen; |
- |
- cipher_def = cwSpec->cipher_def; |
- headerLen = isDTLS ? DTLS_RECORD_HEADER_LENGTH : SSL3_RECORD_HEADER_LENGTH; |
-@@ -2390,86 +2556,117 @@ |
- contentLen = outlen; |
- } |
- |
-- /* |
-- * Add the MAC |
-- */ |
-- rv = ssl3_ComputeRecordMAC( cwSpec, isServer, isDTLS, |
-- type, cwSpec->version, cwSpec->write_seq_num, pIn, contentLen, |
-- wrBuf->buf + headerLen + ivLen + contentLen, &macLen); |
-- if (rv != SECSuccess) { |
-- ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE); |
-- return SECFailure; |
-- } |
-- p1Len = contentLen; |
-- p2Len = macLen; |
-- fragLen = contentLen + macLen; /* needs to be encrypted */ |
-- PORT_Assert(fragLen <= MAX_FRAGMENT_LENGTH + 1024); |
-+ pseudoHeaderLen = ssl3_BuildRecordPseudoHeader( |
-+ pseudoHeader, cwSpec->write_seq_num, type, |
-+ cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_0, cwSpec->version, |
-+ isDTLS, contentLen); |
-+ PORT_Assert(pseudoHeaderLen <= sizeof(pseudoHeader)); |
-+ if (cipher_def->type == type_aead) { |
-+ const int nonceLen = cipher_def->explicit_nonce_size; |
-+ const int tagLen = cipher_def->tag_size; |
- |
-- /* |
-- * Pad the text (if we're doing a block cipher) |
-- * then Encrypt it |
-- */ |
-- if (cipher_def->type == type_block) { |
-- unsigned char * pBuf; |
-- int padding_length; |
-- int i; |
-+ if (headerLen + nonceLen + contentLen + tagLen > wrBuf->space) { |
-+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
-+ return SECFailure; |
-+ } |
- |
-- oddLen = contentLen % cipher_def->block_size; |
-- /* Assume blockSize is a power of two */ |
-- padding_length = cipher_def->block_size - 1 - |
-- ((fragLen) & (cipher_def->block_size - 1)); |
-- fragLen += padding_length + 1; |
-- PORT_Assert((fragLen % cipher_def->block_size) == 0); |
-- |
-- /* Pad according to TLS rules (also acceptable to SSL3). */ |
-- pBuf = &wrBuf->buf[headerLen + ivLen + fragLen - 1]; |
-- for (i = padding_length + 1; i > 0; --i) { |
-- *pBuf-- = padding_length; |
-+ cipherBytes = contentLen; |
-+ rv = cwSpec->aead( |
-+ isServer ? &cwSpec->server : &cwSpec->client, |
-+ PR_FALSE, /* do encrypt */ |
-+ wrBuf->buf + headerLen, /* output */ |
-+ &cipherBytes, /* out len */ |
-+ wrBuf->space - headerLen, /* max out */ |
-+ pIn, contentLen, /* input */ |
-+ pseudoHeader, pseudoHeaderLen); |
-+ if (rv != SECSuccess) { |
-+ PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE); |
-+ return SECFailure; |
- } |
-- /* now, if contentLen is not a multiple of block size, fix it */ |
-- p2Len = fragLen - p1Len; |
-- } |
-- if (p1Len < 256) { |
-- oddLen = p1Len; |
-- p1Len = 0; |
- } else { |
-- p1Len -= oddLen; |
-- } |
-- if (oddLen) { |
-- p2Len += oddLen; |
-- PORT_Assert( (cipher_def->block_size < 2) || \ |
-- (p2Len % cipher_def->block_size) == 0); |
-- memmove(wrBuf->buf + headerLen + ivLen + p1Len, pIn + p1Len, oddLen); |
-- } |
-- if (p1Len > 0) { |
-- int cipherBytesPart1 = -1; |
-- rv = cwSpec->encode( cwSpec->encodeContext, |
-- wrBuf->buf + headerLen + ivLen, /* output */ |
-- &cipherBytesPart1, /* actual outlen */ |
-- p1Len, /* max outlen */ |
-- pIn, p1Len); /* input, and inputlen */ |
-- PORT_Assert(rv == SECSuccess && cipherBytesPart1 == (int) p1Len); |
-- if (rv != SECSuccess || cipherBytesPart1 != (int) p1Len) { |
-- PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE); |
-+ /* |
-+ * Add the MAC |
-+ */ |
-+ rv = ssl3_ComputeRecordMAC(cwSpec, isServer, |
-+ pseudoHeader, pseudoHeaderLen, pIn, contentLen, |
-+ wrBuf->buf + headerLen + ivLen + contentLen, &macLen); |
-+ if (rv != SECSuccess) { |
-+ ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE); |
- return SECFailure; |
- } |
-- cipherBytes += cipherBytesPart1; |
-+ p1Len = contentLen; |
-+ p2Len = macLen; |
-+ fragLen = contentLen + macLen; /* needs to be encrypted */ |
-+ PORT_Assert(fragLen <= MAX_FRAGMENT_LENGTH + 1024); |
-+ |
-+ /* |
-+ * Pad the text (if we're doing a block cipher) |
-+ * then Encrypt it |
-+ */ |
-+ if (cipher_def->type == type_block) { |
-+ unsigned char * pBuf; |
-+ int padding_length; |
-+ int i; |
-+ |
-+ oddLen = contentLen % cipher_def->block_size; |
-+ /* Assume blockSize is a power of two */ |
-+ padding_length = cipher_def->block_size - 1 - |
-+ ((fragLen) & (cipher_def->block_size - 1)); |
-+ fragLen += padding_length + 1; |
-+ PORT_Assert((fragLen % cipher_def->block_size) == 0); |
-+ |
-+ /* Pad according to TLS rules (also acceptable to SSL3). */ |
-+ pBuf = &wrBuf->buf[headerLen + ivLen + fragLen - 1]; |
-+ for (i = padding_length + 1; i > 0; --i) { |
-+ *pBuf-- = padding_length; |
-+ } |
-+ /* now, if contentLen is not a multiple of block size, fix it */ |
-+ p2Len = fragLen - p1Len; |
-+ } |
-+ if (p1Len < 256) { |
-+ oddLen = p1Len; |
-+ p1Len = 0; |
-+ } else { |
-+ p1Len -= oddLen; |
-+ } |
-+ if (oddLen) { |
-+ p2Len += oddLen; |
-+ PORT_Assert( (cipher_def->block_size < 2) || \ |
-+ (p2Len % cipher_def->block_size) == 0); |
-+ memmove(wrBuf->buf + headerLen + ivLen + p1Len, pIn + p1Len, |
-+ oddLen); |
-+ } |
-+ if (p1Len > 0) { |
-+ int cipherBytesPart1 = -1; |
-+ rv = cwSpec->encode( cwSpec->encodeContext, |
-+ wrBuf->buf + headerLen + ivLen, /* output */ |
-+ &cipherBytesPart1, /* actual outlen */ |
-+ p1Len, /* max outlen */ |
-+ pIn, p1Len); /* input, and inputlen */ |
-+ PORT_Assert(rv == SECSuccess && cipherBytesPart1 == (int) p1Len); |
-+ if (rv != SECSuccess || cipherBytesPart1 != (int) p1Len) { |
-+ PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE); |
-+ return SECFailure; |
-+ } |
-+ cipherBytes += cipherBytesPart1; |
-+ } |
-+ if (p2Len > 0) { |
-+ int cipherBytesPart2 = -1; |
-+ rv = cwSpec->encode( cwSpec->encodeContext, |
-+ wrBuf->buf + headerLen + ivLen + p1Len, |
-+ &cipherBytesPart2, /* output and actual outLen */ |
-+ p2Len, /* max outlen */ |
-+ wrBuf->buf + headerLen + ivLen + p1Len, |
-+ p2Len); /* input and inputLen*/ |
-+ PORT_Assert(rv == SECSuccess && cipherBytesPart2 == (int) p2Len); |
-+ if (rv != SECSuccess || cipherBytesPart2 != (int) p2Len) { |
-+ PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE); |
-+ return SECFailure; |
-+ } |
-+ cipherBytes += cipherBytesPart2; |
-+ } |
- } |
-- if (p2Len > 0) { |
-- int cipherBytesPart2 = -1; |
-- rv = cwSpec->encode( cwSpec->encodeContext, |
-- wrBuf->buf + headerLen + ivLen + p1Len, |
-- &cipherBytesPart2, /* output and actual outLen */ |
-- p2Len, /* max outlen */ |
-- wrBuf->buf + headerLen + ivLen + p1Len, |
-- p2Len); /* input and inputLen*/ |
-- PORT_Assert(rv == SECSuccess && cipherBytesPart2 == (int) p2Len); |
-- if (rv != SECSuccess || cipherBytesPart2 != (int) p2Len) { |
-- PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE); |
-- return SECFailure; |
-- } |
-- cipherBytes += cipherBytesPart2; |
-- } |
-+ |
- PORT_Assert(cipherBytes <= MAX_FRAGMENT_LENGTH + 1024); |
- |
- wrBuf->len = cipherBytes + headerLen; |
-@@ -3012,9 +3209,6 @@ |
- static SECStatus |
- ssl3_IllegalParameter(sslSocket *ss) |
- { |
-- PRBool isTLS; |
-- |
-- isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0); |
- (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); |
- PORT_SetError(ss->sec.isServer ? SSL_ERROR_BAD_CLIENT |
- : SSL_ERROR_BAD_SERVER ); |
-@@ -3538,7 +3732,6 @@ |
- } |
- |
- key_material_params.bIsExport = (CK_BBOOL)(kea_def->is_limited); |
-- /* was: (CK_BBOOL)(cipher_def->keygen_mode != kg_strong); */ |
- |
- key_material_params.RandomInfo.pClientRandom = cr; |
- key_material_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH; |
-@@ -9946,7 +10139,6 @@ |
- static void |
- ssl3_RecordKeyLog(sslSocket *ss) |
- { |
-- sslSessionID *sid; |
- SECStatus rv; |
- SECItem *keyData; |
- char buf[14 /* "CLIENT_RANDOM " */ + |
-@@ -9958,8 +10150,6 @@ |
- |
- PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
- |
-- sid = ss->sec.ci.sid; |
-- |
- if (!ssl_keylog_iob) |
- return; |
- |
-@@ -11095,6 +11285,8 @@ |
- unsigned int originalLen = 0; |
- unsigned int good; |
- unsigned int minLength; |
-+ unsigned char header[13]; |
-+ unsigned int headerLen; |
- |
- PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
- |
-@@ -11171,12 +11363,14 @@ |
- /* With >= TLS 1.1, CBC records have an explicit IV. */ |
- minLength += cipher_def->iv_size; |
- } |
-+ } else if (cipher_def->type == type_aead) { |
-+ minLength = cipher_def->explicit_nonce_size + cipher_def->tag_size; |
- } |
- |
- /* We can perform this test in variable time because the record's total |
- * length and the ciphersuite are both public knowledge. */ |
- if (cText->buf->len < minLength) { |
-- goto decrypt_loser; |
-+ goto decrypt_loser; |
- } |
- |
- if (cipher_def->type == type_block && |
-@@ -11244,78 +11438,104 @@ |
- return SECFailure; |
- } |
- |
-- if (cipher_def->type == type_block && |
-- ((cText->buf->len - ivLen) % cipher_def->block_size) != 0) { |
-- goto decrypt_loser; |
-- } |
-+ rType = cText->type; |
-+ if (cipher_def->type == type_aead) { |
-+ /* XXX For many AEAD ciphers, the plaintext is shorter than the |
-+ * ciphertext by a fixed byte count, but it is not true in general. |
-+ * Each AEAD cipher should provide a function that returns the |
-+ * plaintext length for a given ciphertext. */ |
-+ unsigned int decryptedLen = |
-+ cText->buf->len - cipher_def->explicit_nonce_size - |
-+ cipher_def->tag_size; |
-+ headerLen = ssl3_BuildRecordPseudoHeader( |
-+ header, IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num, |
-+ rType, isTLS, cText->version, IS_DTLS(ss), decryptedLen); |
-+ PORT_Assert(headerLen <= sizeof(header)); |
-+ rv = crSpec->aead( |
-+ ss->sec.isServer ? &crSpec->client : &crSpec->server, |
-+ PR_TRUE, /* do decrypt */ |
-+ plaintext->buf, /* out */ |
-+ (int*) &plaintext->len, /* outlen */ |
-+ plaintext->space, /* maxout */ |
-+ cText->buf->buf, /* in */ |
-+ cText->buf->len, /* inlen */ |
-+ header, headerLen); |
-+ if (rv != SECSuccess) { |
-+ good = 0; |
-+ } |
-+ } else { |
-+ if (cipher_def->type == type_block && |
-+ ((cText->buf->len - ivLen) % cipher_def->block_size) != 0) { |
-+ goto decrypt_loser; |
-+ } |
- |
-- /* decrypt from cText buf to plaintext. */ |
-- rv = crSpec->decode( |
-- crSpec->decodeContext, plaintext->buf, (int *)&plaintext->len, |
-- plaintext->space, cText->buf->buf + ivLen, cText->buf->len - ivLen); |
-- if (rv != SECSuccess) { |
-- goto decrypt_loser; |
-- } |
-+ /* decrypt from cText buf to plaintext. */ |
-+ rv = crSpec->decode( |
-+ crSpec->decodeContext, plaintext->buf, (int *)&plaintext->len, |
-+ plaintext->space, cText->buf->buf + ivLen, cText->buf->len - ivLen); |
-+ if (rv != SECSuccess) { |
-+ goto decrypt_loser; |
-+ } |
- |
-- PRINT_BUF(80, (ss, "cleartext:", plaintext->buf, plaintext->len)); |
-+ PRINT_BUF(80, (ss, "cleartext:", plaintext->buf, plaintext->len)); |
- |
-- originalLen = plaintext->len; |
-+ originalLen = plaintext->len; |
- |
-- /* If it's a block cipher, check and strip the padding. */ |
-- if (cipher_def->type == type_block) { |
-- const unsigned int blockSize = cipher_def->block_size; |
-- const unsigned int macSize = crSpec->mac_size; |
-+ /* If it's a block cipher, check and strip the padding. */ |
-+ if (cipher_def->type == type_block) { |
-+ const unsigned int blockSize = cipher_def->block_size; |
-+ const unsigned int macSize = crSpec->mac_size; |
- |
-- if (crSpec->version <= SSL_LIBRARY_VERSION_3_0) { |
-- good &= SECStatusToMask(ssl_RemoveSSLv3CBCPadding( |
-- plaintext, blockSize, macSize)); |
-- } else { |
-- good &= SECStatusToMask(ssl_RemoveTLSCBCPadding( |
-- plaintext, macSize)); |
-+ if (!isTLS) { |
-+ good &= SECStatusToMask(ssl_RemoveSSLv3CBCPadding( |
-+ plaintext, blockSize, macSize)); |
-+ } else { |
-+ good &= SECStatusToMask(ssl_RemoveTLSCBCPadding( |
-+ plaintext, macSize)); |
-+ } |
- } |
-- } |
- |
-- /* compute the MAC */ |
-- rType = cText->type; |
-- if (cipher_def->type == type_block) { |
-- rv = ssl3_ComputeRecordMACConstantTime( |
-- crSpec, (PRBool)(!ss->sec.isServer), |
-- IS_DTLS(ss), rType, cText->version, |
-- IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num, |
-- plaintext->buf, plaintext->len, originalLen, |
-- hash, &hashBytes); |
-+ /* compute the MAC */ |
-+ headerLen = ssl3_BuildRecordPseudoHeader( |
-+ header, IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num, |
-+ rType, isTLS, cText->version, IS_DTLS(ss), |
-+ plaintext->len - crSpec->mac_size); |
-+ PORT_Assert(headerLen <= sizeof(header)); |
-+ if (cipher_def->type == type_block) { |
-+ rv = ssl3_ComputeRecordMACConstantTime( |
-+ crSpec, (PRBool)(!ss->sec.isServer), header, headerLen, |
-+ plaintext->buf, plaintext->len, originalLen, |
-+ hash, &hashBytes); |
- |
-- ssl_CBCExtractMAC(plaintext, originalLen, givenHashBuf, |
-- crSpec->mac_size); |
-- givenHash = givenHashBuf; |
-+ ssl_CBCExtractMAC(plaintext, originalLen, givenHashBuf, |
-+ crSpec->mac_size); |
-+ givenHash = givenHashBuf; |
- |
-- /* plaintext->len will always have enough space to remove the MAC |
-- * because in ssl_Remove{SSLv3|TLS}CBCPadding we only adjust |
-- * plaintext->len if the result has enough space for the MAC and we |
-- * tested the unadjusted size against minLength, above. */ |
-- plaintext->len -= crSpec->mac_size; |
-- } else { |
-- /* This is safe because we checked the minLength above. */ |
-- plaintext->len -= crSpec->mac_size; |
-+ /* plaintext->len will always have enough space to remove the MAC |
-+ * because in ssl_Remove{SSLv3|TLS}CBCPadding we only adjust |
-+ * plaintext->len if the result has enough space for the MAC and we |
-+ * tested the unadjusted size against minLength, above. */ |
-+ plaintext->len -= crSpec->mac_size; |
-+ } else { |
-+ /* This is safe because we checked the minLength above. */ |
-+ plaintext->len -= crSpec->mac_size; |
- |
-- rv = ssl3_ComputeRecordMAC( |
-- crSpec, (PRBool)(!ss->sec.isServer), |
-- IS_DTLS(ss), rType, cText->version, |
-- IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num, |
-- plaintext->buf, plaintext->len, |
-- hash, &hashBytes); |
-+ rv = ssl3_ComputeRecordMAC( |
-+ crSpec, (PRBool)(!ss->sec.isServer), header, headerLen, |
-+ plaintext->buf, plaintext->len, hash, &hashBytes); |
- |
-- /* We can read the MAC directly from the record because its location is |
-- * public when a stream cipher is used. */ |
-- givenHash = plaintext->buf + plaintext->len; |
-- } |
-+ /* We can read the MAC directly from the record because its location |
-+ * is public when a stream cipher is used. */ |
-+ givenHash = plaintext->buf + plaintext->len; |
-+ } |
- |
-- good &= SECStatusToMask(rv); |
-+ good &= SECStatusToMask(rv); |
- |
-- if (hashBytes != (unsigned)crSpec->mac_size || |
-- NSS_SecureMemcmp(givenHash, hash, crSpec->mac_size) != 0) { |
-- /* We're allowed to leak whether or not the MAC check was correct */ |
-- good = 0; |
-+ if (hashBytes != (unsigned)crSpec->mac_size || |
-+ NSS_SecureMemcmp(givenHash, hash, crSpec->mac_size) != 0) { |
-+ /* We're allowed to leak whether or not the MAC check was correct */ |
-+ good = 0; |
-+ } |
- } |
- |
- if (good == 0) { |
-Index: net/third_party/nss/ssl/sslenum.c |
-=================================================================== |
---- net/third_party/nss/ssl/sslenum.c (revision 217715) |
-+++ net/third_party/nss/ssl/sslenum.c (working copy) |
-@@ -29,6 +29,14 @@ |
- * Finally, update the ssl_V3_SUITES_IMPLEMENTED macro in sslimpl.h. |
- */ |
- const PRUint16 SSL_ImplementedCiphers[] = { |
-+ /* AES-GCM */ |
-+#ifdef NSS_ENABLE_ECC |
-+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, |
-+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, |
-+#endif /* NSS_ENABLE_ECC */ |
-+ TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, |
-+ TLS_RSA_WITH_AES_128_GCM_SHA256, |
-+ |
- /* 256-bit */ |
- #ifdef NSS_ENABLE_ECC |
- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, |
-Index: net/third_party/nss/ssl/sslproto.h |
-=================================================================== |
---- net/third_party/nss/ssl/sslproto.h (revision 217715) |
-+++ net/third_party/nss/ssl/sslproto.h (working copy) |
-@@ -162,6 +162,10 @@ |
- |
- #define TLS_RSA_WITH_SEED_CBC_SHA 0x0096 |
- |
-+#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 |
-+ |
- /* TLS "Signaling Cipher Suite Value" (SCSV). May be requested by client. |
- * Must NEVER be chosen by server. SSL 3.0 server acknowledges by sending |
- * back an empty Renegotiation Info (RI) server hello extension. |
-@@ -204,6 +208,11 @@ |
- #define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023 |
- #define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027 |
- |
-+#define TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B |
-+#define TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0xC02D |
-+#define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F |
-+#define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 |
-+ |
- /* Netscape "experimental" cipher suites. */ |
- #define SSL_RSA_OLDFIPS_WITH_3DES_EDE_CBC_SHA 0xffe0 |
- #define SSL_RSA_OLDFIPS_WITH_DES_CBC_SHA 0xffe1 |
-Index: net/third_party/nss/ssl/sslt.h |
-=================================================================== |
---- net/third_party/nss/ssl/sslt.h (revision 217715) |
-+++ net/third_party/nss/ssl/sslt.h (working copy) |
-@@ -91,9 +91,10 @@ |
- ssl_calg_3des = 4, |
- ssl_calg_idea = 5, |
- ssl_calg_fortezza = 6, /* deprecated, now unused */ |
-- ssl_calg_aes = 7, /* coming soon */ |
-+ ssl_calg_aes = 7, |
- ssl_calg_camellia = 8, |
-- ssl_calg_seed = 9 |
-+ ssl_calg_seed = 9, |
-+ ssl_calg_aes_gcm = 10 |
- } SSLCipherAlgorithm; |
- |
- typedef enum { |
-@@ -102,7 +103,8 @@ |
- ssl_mac_sha = 2, |
- ssl_hmac_md5 = 3, /* TLS HMAC version of mac_md5 */ |
- ssl_hmac_sha = 4, /* TLS HMAC version of mac_sha */ |
-- ssl_hmac_sha256 = 5 |
-+ ssl_hmac_sha256 = 5, |
-+ ssl_mac_aead = 6 |
- } SSLMACAlgorithm; |
- |
- typedef enum { |
-@@ -158,6 +160,9 @@ |
- PRUint16 effectiveKeyBits; |
- |
- /* MAC info */ |
-+ /* AEAD ciphers don't have a MAC. For an AEAD cipher, macAlgorithmName |
-+ * is "AEAD", macAlgorithm is ssl_mac_aead, and macBits is the length in |
-+ * bits of the authentication tag. */ |
- const char * macAlgorithmName; |
- SSLMACAlgorithm macAlgorithm; |
- PRUint16 macBits; |