Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(133)

Side by Side Diff: net/socket/ssl_client_socket_nss.cc

Issue 75663004: net: boost AES-GCM ciphers if the machine has AES-NI. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove unused variable Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived 5 // This file includes code SSLClientSocketNSS::DoVerifyCertComplete() derived
6 // from AuthCertificateCallback() in 6 // from AuthCertificateCallback() in
7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp. 7 // mozilla/security/manager/ssl/src/nsNSSCallbacks.cpp.
8 8
9 /* ***** BEGIN LICENSE BLOCK ***** 9 /* ***** BEGIN LICENSE BLOCK *****
10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 10 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 #include <sslproto.h> 61 #include <sslproto.h>
62 62
63 #include <algorithm> 63 #include <algorithm>
64 #include <limits> 64 #include <limits>
65 #include <map> 65 #include <map>
66 66
67 #include "base/bind.h" 67 #include "base/bind.h"
68 #include "base/bind_helpers.h" 68 #include "base/bind_helpers.h"
69 #include "base/callback_helpers.h" 69 #include "base/callback_helpers.h"
70 #include "base/compiler_specific.h" 70 #include "base/compiler_specific.h"
71 #include "base/cpu.h"
71 #include "base/logging.h" 72 #include "base/logging.h"
72 #include "base/memory/singleton.h" 73 #include "base/memory/singleton.h"
73 #include "base/metrics/histogram.h" 74 #include "base/metrics/histogram.h"
74 #include "base/single_thread_task_runner.h" 75 #include "base/single_thread_task_runner.h"
75 #include "base/stl_util.h" 76 #include "base/stl_util.h"
76 #include "base/strings/string_number_conversions.h" 77 #include "base/strings/string_number_conversions.h"
77 #include "base/strings/string_util.h" 78 #include "base/strings/string_util.h"
78 #include "base/strings/stringprintf.h" 79 #include "base/strings/stringprintf.h"
79 #include "base/thread_task_runner_handle.h" 80 #include "base/thread_task_runner_handle.h"
80 #include "base/threading/thread_restrictions.h" 81 #include "base/threading/thread_restrictions.h"
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 switch (err) { 484 switch (err) {
484 // If the server closed on us, it is a protocol error. 485 // If the server closed on us, it is a protocol error.
485 // Some TLS-intolerant servers do this when we request TLS. 486 // Some TLS-intolerant servers do this when we request TLS.
486 case PR_END_OF_FILE_ERROR: 487 case PR_END_OF_FILE_ERROR:
487 return ERR_SSL_PROTOCOL_ERROR; 488 return ERR_SSL_PROTOCOL_ERROR;
488 default: 489 default:
489 return MapNSSClientError(err); 490 return MapNSSClientError(err);
490 } 491 }
491 } 492 }
492 493
494 // CiphersRemove takes a zero-terminated array of cipher suite ids in
495 // |to_remove| and sets every instance of them in |ciphers| to zero. It returns
496 // true if it found and removed every element of |to_remove|. It assumes that
497 // there are no duplicates in |ciphers| nor in |to_remove|.
498 bool CiphersRemove(const uint16* to_remove, uint16* ciphers, size_t num) {
499 size_t num_remove, found = 0;
500
501 for (num_remove = 0; ; num_remove++) {
502 if (to_remove[num_remove] == 0)
503 break;
504 }
505
506 for (size_t i = 0; i < num; i++) {
507 for (size_t j = 0; j < num_remove; j++) {
508 if (to_remove[j] == ciphers[i]) {
509 ciphers[i] = 0;
510 found++;
511 break;
512 }
513 }
514 }
515
516 return found == num_remove;
517 }
518
519 // CiphersCompact takes an array of cipher suite ids in |ciphers|, where some
520 // entries are zero, and moves the entries so that all the non-zero elements
521 // are compacted at the end of the array.
522 size_t CiphersCompact(uint16* ciphers, size_t num) {
523 size_t j = num - 1;
524
525 for (size_t i = num - 1; i < num; i--) {
526 printf("@%u %d %u\n", (unsigned) i, ciphers[i], (unsigned) j);
527 if (ciphers[i] == 0)
528 continue;
529 ciphers[j--] = ciphers[i];
530 }
531 return j+1;
532 }
533
534 // CiphersCopy copies the zero-terminated array |in| to |out|.
535 size_t CiphersCopy(const uint16* in, uint16* out) {
536 for (size_t i = 0; ; i++) {
537 if (in[i] == 0)
538 return i;
539 out[i] = in[i];
540 }
541 }
542
493 } // namespace 543 } // namespace
494 544
495 // SSLClientSocketNSS::Core provides a thread-safe, ref-counted core that is 545 // SSLClientSocketNSS::Core provides a thread-safe, ref-counted core that is
496 // able to marshal data between NSS functions and an underlying transport 546 // able to marshal data between NSS functions and an underlying transport
497 // socket. 547 // socket.
498 // 548 //
499 // All public functions are meant to be called from the network task runner, 549 // All public functions are meant to be called from the network task runner,
500 // and any callbacks supplied will be invoked there as well, provided that 550 // and any callbacks supplied will be invoked there as well, provided that
501 // Detach() has not been called yet. 551 // Detach() has not been called yet.
502 // 552 //
(...skipping 2608 matching lines...) Expand 10 before | Expand all | Expand 10 after
3111 } 3161 }
3112 3162
3113 for (std::vector<uint16>::const_iterator it = 3163 for (std::vector<uint16>::const_iterator it =
3114 ssl_config_.disabled_cipher_suites.begin(); 3164 ssl_config_.disabled_cipher_suites.begin();
3115 it != ssl_config_.disabled_cipher_suites.end(); ++it) { 3165 it != ssl_config_.disabled_cipher_suites.end(); ++it) {
3116 // This will fail if the specified cipher is not implemented by NSS, but 3166 // This will fail if the specified cipher is not implemented by NSS, but
3117 // the failure is harmless. 3167 // the failure is harmless.
3118 SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE); 3168 SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE);
3119 } 3169 }
3120 3170
3171 /* Our top preference cipher suites are either forward-secure AES-GCM or
3172 * forward secure ChaCha20-Poly1305. If the local machine has AES-NI then we
3173 * prefer AES-GCM, otherwise ChaCha20. The remainder of the cipher suite
3174 * preference is inheriented from NSS. */
3175 static const uint16 chacha_ciphers[] = {
3176 0xcc14 /* TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 */,
3177 0xcc13 /* TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 */,
3178 0,
3179 };
3180 static const uint16 aes_gcm_ciphers[] = {
3181 0xc02b /* TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 */,
3182 0xc02f /* TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 */,
3183 0x9e /* TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 */,
3184 0,
3185 };
3186 const PRUint16 *all_ciphers = SSL_GetImplementedCiphers();
3187 const size_t num_ciphers = SSL_GetNumImplementedCiphers();
3188 scoped_ptr<uint16[]> ciphers(new uint16[num_ciphers]);
3189 memcpy(ciphers.get(), all_ciphers, sizeof(uint16)*num_ciphers);
3190
3191 if (CiphersRemove(chacha_ciphers, ciphers.get(), num_ciphers) &&
3192 CiphersRemove(aes_gcm_ciphers, ciphers.get(), num_ciphers)) {
3193 CiphersCompact(ciphers.get(), num_ciphers);
3194
3195 const uint16 *preference_ciphers = chacha_ciphers;
3196 const uint16 *other_ciphers = aes_gcm_ciphers;
3197 if (base::CPU().has_aesni()) {
wtc 2013/11/19 23:00:44 Since this won't change over time, we should ideal
agl 2013/11/20 18:21:07 Done.
3198 preference_ciphers = aes_gcm_ciphers;
3199 other_ciphers = chacha_ciphers;
3200 }
3201 unsigned i = CiphersCopy(preference_ciphers, ciphers.get());
3202 CiphersCopy(other_ciphers, &ciphers[i]);
3203
3204 rv = SSL_CipherOrderSet(nss_fd_, ciphers.get(), num_ciphers);
3205 if (rv != SECSuccess) {
3206 LogFailedNSSFunction(net_log_, "SSL_CipherOrderSet", "");
3207 }
3208 }
3209
3121 // Support RFC 5077 3210 // Support RFC 5077
3122 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_TRUE); 3211 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_TRUE);
3123 if (rv != SECSuccess) { 3212 if (rv != SECSuccess) {
3124 LogFailedNSSFunction( 3213 LogFailedNSSFunction(
3125 net_log_, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS"); 3214 net_log_, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS");
3126 } 3215 }
3127 3216
3128 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_FALSE_START, 3217 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_FALSE_START,
3129 ssl_config_.false_start_enabled); 3218 ssl_config_.false_start_enabled);
3130 if (rv != SECSuccess) 3219 if (rv != SECSuccess)
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
3479 EnsureThreadIdAssigned(); 3568 EnsureThreadIdAssigned();
3480 base::AutoLock auto_lock(lock_); 3569 base::AutoLock auto_lock(lock_);
3481 return valid_thread_id_ == base::PlatformThread::CurrentId(); 3570 return valid_thread_id_ == base::PlatformThread::CurrentId();
3482 } 3571 }
3483 3572
3484 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const { 3573 ServerBoundCertService* SSLClientSocketNSS::GetServerBoundCertService() const {
3485 return server_bound_cert_service_; 3574 return server_bound_cert_service_;
3486 } 3575 }
3487 3576
3488 } // namespace net 3577 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698