Index: net/third_party/nss/patches/aesgcmchromium.patch |
=================================================================== |
--- net/third_party/nss/patches/aesgcmchromium.patch (revision 0) |
+++ net/third_party/nss/patches/aesgcmchromium.patch (revision 0) |
@@ -0,0 +1,117 @@ |
+--- net/third_party/nss/ssl/ssl3con.c.orig 2013-08-14 14:22:50.479780305 -0700 |
++++ net/third_party/nss/ssl/ssl3con.c 2013-08-14 14:23:57.670788603 -0700 |
+@@ -44,6 +44,9 @@ |
+ #ifdef NSS_ENABLE_ZLIB |
+ #include "zlib.h" |
+ #endif |
++#ifdef LINUX |
++#include <dlfcn.h> |
++#endif |
+ |
+ #ifndef PK11_SETATTRS |
+ #define PK11_SETATTRS(x,id,v,l) (x)->type = (id); \ |
+@@ -1807,6 +1810,69 @@ ssl3_BuildRecordPseudoHeader(unsigned ch |
+ return 13; |
+ } |
+ |
++typedef SECStatus (*PK11CryptFcn)( |
++ PK11SymKey *symKey, CK_MECHANISM_TYPE mechanism, SECItem *param, |
++ unsigned char *out, unsigned int *outLen, unsigned int maxLen, |
++ const unsigned char *in, unsigned int inLen); |
++ |
++static PK11CryptFcn pk11_encrypt = NULL; |
++static PK11CryptFcn pk11_decrypt = NULL; |
++ |
++static PRCallOnceType resolvePK11CryptOnce; |
++ |
++static PRStatus |
++ssl3_ResolvePK11CryptFunctions(void) |
++{ |
++#ifdef LINUX |
++ /* On Linux we use the system NSS libraries. Look up the PK11_Encrypt and |
++ * PK11_Decrypt functions at run time. */ |
++ void *handle = dlopen(NULL, RTLD_LAZY); |
++ if (!handle) { |
++ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
++ return PR_FAILURE; |
++ } |
++ pk11_encrypt = (PK11CryptFcn)dlsym(handle, "PK11_Encrypt"); |
++ pk11_decrypt = (PK11CryptFcn)dlsym(handle, "PK11_Decrypt"); |
++ dlclose(handle); |
++ return PR_SUCCESS; |
++#else |
++ /* On other platforms we use our own copy of NSS. PK11_Encrypt and |
++ * PK11_Decrypt are known to be available. */ |
++ pk11_encrypt = PK11_Encrypt; |
++ pk11_decrypt = PK11_Decrypt; |
++ return PR_SUCCESS; |
++#endif |
++} |
++ |
++/* |
++ * In NSS 3.15, PK11_Encrypt and PK11_Decrypt were added to provide access |
++ * to the AES GCM implementation in the NSS softoken. So the presence of |
++ * these two functions implies the NSS version supports AES GCM. |
++ */ |
++static PRBool |
++ssl3_HasGCMSupport(void) |
++{ |
++ (void)PR_CallOnce(&resolvePK11CryptOnce, ssl3_ResolvePK11CryptFunctions); |
++ return pk11_encrypt != NULL; |
++} |
++ |
++/* On this socket, disable the GCM cipher suites */ |
++SECStatus |
++ssl3_DisableGCMSuites(sslSocket * ss) |
++{ |
++ unsigned int i; |
++ |
++ for (i = 0; i < PR_ARRAY_SIZE(cipher_suite_defs); i++) { |
++ const ssl3CipherSuiteDef *cipher_def = &cipher_suite_defs[i]; |
++ if (cipher_def->bulk_cipher_alg == cipher_aes_128_gcm) { |
++ SECStatus rv = ssl3_CipherPrefSet(ss, cipher_def->cipher_suite, |
++ PR_FALSE); |
++ PORT_Assert(rv == SECSuccess); /* else is coding error */ |
++ } |
++ } |
++ return SECSuccess; |
++} |
++ |
+ static SECStatus |
+ ssl3_AESGCM(ssl3KeyMaterial *keys, |
+ PRBool doDecrypt, |
+@@ -1869,10 +1935,10 @@ ssl3_AESGCM(ssl3KeyMaterial *keys, |
+ gcmParams.ulTagBits = tagSize * 8; |
+ |
+ if (doDecrypt) { |
+- rv = PK11_Decrypt(keys->write_key, CKM_AES_GCM, ¶m, out, &uOutLen, |
++ 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, |
++ rv = pk11_encrypt(keys->write_key, CKM_AES_GCM, ¶m, out, &uOutLen, |
+ maxout, in, inlen); |
+ } |
+ *outlen += (int) uOutLen; |
+@@ -5071,6 +5137,10 @@ ssl3_SendClientHello(sslSocket *ss, PRBo |
+ ssl3_DisableNonDTLSSuites(ss); |
+ } |
+ |
++ if (!ssl3_HasGCMSupport()) { |
++ ssl3_DisableGCMSuites(ss); |
++ } |
++ |
+ /* how many suites are permitted by policy and user preference? */ |
+ num_suites = count_cipher_suites(ss, ss->ssl3.policy, PR_TRUE); |
+ if (!num_suites) |
+@@ -7776,6 +7846,10 @@ ssl3_HandleClientHello(sslSocket *ss, SS |
+ ssl3_DisableNonDTLSSuites(ss); |
+ } |
+ |
++ if (!ssl3_HasGCMSupport()) { |
++ ssl3_DisableGCMSuites(ss); |
++ } |
++ |
+ #ifdef PARANOID |
+ /* Look for a matching cipher suite. */ |
+ j = ssl3_config_match_init(ss); |