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