• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &param, out, &uOutLen,
88+	rv = pk11_decrypt(keys->write_key, CKM_AES_GCM, &param, out, &uOutLen,
89 			  maxout, in, inlen);
90     } else {
91-	rv = PK11_Encrypt(keys->write_key, CKM_AES_GCM, &param, out, &uOutLen,
92+	rv = pk11_encrypt(keys->write_key, CKM_AES_GCM, &param, 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