Home | History | Annotate | Download | only in patches
      1 diff -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, &param, out, &uOutLen,
     89 +	rv = pk11_decrypt(keys->write_key, CKM_AES_GCM, &param, out, &uOutLen,
     90  			  maxout, in, inlen);
     91      } else {
     92 -	rv = PK11_Encrypt(keys->write_key, CKM_AES_GCM, &param, out, &uOutLen,
     93 +	rv = pk11_encrypt(keys->write_key, CKM_AES_GCM, &param, 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