1diff -pu a/nss/lib/ssl/ssl3con.c b/nss/lib/ssl/ssl3con.c 2--- a/nss/lib/ssl/ssl3con.c 2014-01-17 18:04:43.127747463 -0800 3+++ b/nss/lib/ssl/ssl3con.c 2014-01-17 18:06:21.919386088 -0800 4@@ -44,6 +44,9 @@ 5 #ifdef NSS_ENABLE_ZLIB 6 #include "zlib.h" 7 #endif 8+#ifdef LINUX 9+#include <dlfcn.h> 10+#endif 11 12 #ifndef PK11_SETATTRS 13 #define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \ 14@@ -1842,6 +1845,69 @@ ssl3_BuildRecordPseudoHeader(unsigned ch 15 return 13; 16 } 17 18+typedef SECStatus (*PK11CryptFcn)( 19+ PK11SymKey *symKey, CK_MECHANISM_TYPE mechanism, SECItem *param, 20+ unsigned char *out, unsigned int *outLen, unsigned int maxLen, 21+ const unsigned char *in, unsigned int inLen); 22+ 23+static PK11CryptFcn pk11_encrypt = NULL; 24+static PK11CryptFcn pk11_decrypt = NULL; 25+ 26+static PRCallOnceType resolvePK11CryptOnce; 27+ 28+static PRStatus 29+ssl3_ResolvePK11CryptFunctions(void) 30+{ 31+#ifdef LINUX 32+ /* On Linux we use the system NSS libraries. Look up the PK11_Encrypt and 33+ * PK11_Decrypt functions at run time. */ 34+ void *handle = dlopen(NULL, RTLD_LAZY); 35+ if (!handle) { 36+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 37+ return PR_FAILURE; 38+ } 39+ pk11_encrypt = (PK11CryptFcn)dlsym(handle, "PK11_Encrypt"); 40+ pk11_decrypt = (PK11CryptFcn)dlsym(handle, "PK11_Decrypt"); 41+ dlclose(handle); 42+ return PR_SUCCESS; 43+#else 44+ /* On other platforms we use our own copy of NSS. PK11_Encrypt and 45+ * PK11_Decrypt are known to be available. */ 46+ pk11_encrypt = PK11_Encrypt; 47+ pk11_decrypt = PK11_Decrypt; 48+ return PR_SUCCESS; 49+#endif 50+} 51+ 52+/* 53+ * In NSS 3.15, PK11_Encrypt and PK11_Decrypt were added to provide access 54+ * to the AES GCM implementation in the NSS softoken. So the presence of 55+ * these two functions implies the NSS version supports AES GCM. 56+ */ 57+static PRBool 58+ssl3_HasGCMSupport(void) 59+{ 60+ (void)PR_CallOnce(&resolvePK11CryptOnce, ssl3_ResolvePK11CryptFunctions); 61+ return pk11_encrypt != NULL; 62+} 63+ 64+/* On this socket, disable the GCM cipher suites */ 65+SECStatus 66+ssl3_DisableGCMSuites(sslSocket * ss) 67+{ 68+ unsigned int i; 69+ 70+ for (i = 0; i < PR_ARRAY_SIZE(cipher_suite_defs); i++) { 71+ const ssl3CipherSuiteDef *cipher_def = &cipher_suite_defs[i]; 72+ if (cipher_def->bulk_cipher_alg == cipher_aes_128_gcm) { 73+ SECStatus rv = ssl3_CipherPrefSet(ss, cipher_def->cipher_suite, 74+ PR_FALSE); 75+ PORT_Assert(rv == SECSuccess); /* else is coding error */ 76+ } 77+ } 78+ return SECSuccess; 79+} 80+ 81 static SECStatus 82 ssl3_AESGCM(ssl3KeyMaterial *keys, 83 PRBool doDecrypt, 84@@ -1893,10 +1959,10 @@ ssl3_AESGCM(ssl3KeyMaterial *keys, 85 gcmParams.ulTagBits = tagSize * 8; 86 87 if (doDecrypt) { 88- rv = PK11_Decrypt(keys->write_key, CKM_AES_GCM, ¶m, out, &uOutLen, 89+ rv = pk11_decrypt(keys->write_key, CKM_AES_GCM, ¶m, out, &uOutLen, 90 maxout, in, inlen); 91 } else { 92- rv = PK11_Encrypt(keys->write_key, CKM_AES_GCM, ¶m, out, &uOutLen, 93+ rv = pk11_encrypt(keys->write_key, CKM_AES_GCM, ¶m, out, &uOutLen, 94 maxout, in, inlen); 95 } 96 *outlen += (int) uOutLen; 97@@ -5103,6 +5169,10 @@ ssl3_SendClientHello(sslSocket *ss, PRBo 98 ssl3_DisableNonDTLSSuites(ss); 99 } 100 101+ if (!ssl3_HasGCMSupport()) { 102+ ssl3_DisableGCMSuites(ss); 103+ } 104+ 105 /* how many suites are permitted by policy and user preference? */ 106 num_suites = count_cipher_suites(ss, ss->ssl3.policy, PR_TRUE); 107 if (!num_suites) { 108@@ -8080,6 +8150,10 @@ ssl3_HandleClientHello(sslSocket *ss, SS 109 ssl3_DisableNonDTLSSuites(ss); 110 } 111 112+ if (!ssl3_HasGCMSupport()) { 113+ ssl3_DisableGCMSuites(ss); 114+ } 115+ 116 #ifdef PARANOID 117 /* Look for a matching cipher suite. */ 118 j = ssl3_config_match_init(ss); 119