- add sources.
[platform/framework/web/crosswalk.git] / src / net / third_party / nss / patches / aesgcmchromium.patch
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);