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