Skip to content

Commit

Permalink
Landing Recent QUIC changes until 06/01/2015.
Browse files Browse the repository at this point in the history
Fix QUIC tests not to use stream ID 3.

Stream ID 3 is reserver for headers, but some tests were using it for data
stream. Fixed them to use stream ID 5.

relnote: test cleanup: don't use stream ID 3 for data streams in tests.

Merge internal change: 94937344
https://codereview.chromium.org/1162263010/

relnote: Added FEC send policy to send FEC packet when FEC group is
closed or when FEC timer goes off (same as the current code). This is
the default policy. Thus this change doesn't change current behavior.

Added a new policy to send FEC only when FEC timer goes off. This policy
is not enabled in the code.

When FEC group is closed (or reset) because of the new policy,
packet_generator calls delgate's OnResetFecGroup. Implementation of this
method in QuicConnection cancel's the FEC timer (because there is no FEC
packet outstanding).

Changed packet generator's unittests to run when each policy is enabled.

Merge internal change: 94774277
https://codereview.chromium.org/1145893012/

relnote:  Low risk. Add non-varz counter for CHLOs with server nonces.

Added support to the QuicCryptoServerStream for the number of
handshake messages that contain server nonces.

Previously, this class was just counting handshake messages,
irregardless of server nonces.  If encryption was established with
just one handshake message, the jetstream session would conclude this
was a 0-RTT connection.

Unfortunately, when stateless rejects come into play, the first
handshake after an SREJ will cause encryption to be established in a
single handshake.  However, this should not be counted as a 0-RTT
connection.

The solution is to separately keep track of handshake messages that
contain server nonces.  If a connection is established in one
handshake and contains a server-nonce, it is NOT a 0-RTT connection.

Added support to the crypto stream tests as well.

Merge internal change: 94767471
https://codereview.chromium.org/1158073004/

Add QUIC connection options for IW3, 20, and 50 for initial CWND
experiments.

Merge internal change: 94763199
https://codereview.chromium.org/1159113004/

relnote:  Low risk. Changed some incorrect documentation in
quic_crypto_server_config.h

The following is the internal message:

Add varz for counting crypto handshake reject messages.

Added two new varz for keeping track of REJ/SREJ messages sent.

Whenever the server processes a client hello, it now checks the crypto
result.  If the result is some kind of REJ/SREJ message, it now
increments the appropriate varz.

The tests for these varz will be included in a forthcoming CL that
includes the end_to_end_test and adds support for stateless rejects at
the server.

Changed some incorrect documentation in quic_crypto_server_config.h

Merge internal change: 94762526
https://codereview.chromium.org/1162433007/

relnote: Minor simplification of QUIC's AeadBaseDecrypter.

Made the corresponding changes from internal code to NSS and OpenSSL
implementations.

Merge internal change: 94586771
https://codereview.chromium.org/1152173016/

relnote: Merge QuicEncrypter's Encrypt into EncryptPacket and avoid an
extra allocation and copy in NullEncrypter.  No functional change.

Merge internal change: 94569655
https://codereview.chromium.org/1164803004/

relnote: Remove an unnecessary virtual method from the QuicEncrypter
interface.  No functional change.

More cleanup and optimization to follow.

Merge internal change: 94539011
https://codereview.chromium.org/1160263004/

Update quic_client_bin.cc to use the correct hostname (not IP) in the
ServerID.

Merge internal change: 94480774
https://codereview.chromium.org/1152623007/

relnote: Remove obsolete QuicStreamFrame constructor.  No functional
change.

Merge internal change: 94293525
https://codereview.chromium.org/1168443002/

relnote: Simplify the creation of QuicStreamFrame by directly
constructing the buffer and wrapping it in an IOVector.

Eliminates extra creation of temporary IOVectors and saves a copy in
GetStreamData::GetDataAsString. Estimated to save 2% of CPU.

Merge internal change: 94214497
https://codereview.chromium.org/1157403008/

R=rch@chromium.org

Review URL: https://codereview.chromium.org/1152923007

Cr-Commit-Position: refs/heads/master@{#332769}
  • Loading branch information
rtenneti authored and Commit bot committed Jun 4, 2015
1 parent 8da589a commit a4228ea
Show file tree
Hide file tree
Showing 55 changed files with 894 additions and 498 deletions.
15 changes: 15 additions & 0 deletions net/quic/congestion_control/tcp_cubic_sender.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,26 @@ TcpCubicSender::~TcpCubicSender() {
void TcpCubicSender::SetFromConfig(const QuicConfig& config,
Perspective perspective) {
if (perspective == Perspective::IS_SERVER) {
if (config.HasReceivedConnectionOptions() &&
ContainsQuicTag(config.ReceivedConnectionOptions(), kIW03)) {
// Initial window experiment.
congestion_window_ = 3;
}
if (config.HasReceivedConnectionOptions() &&
ContainsQuicTag(config.ReceivedConnectionOptions(), kIW10)) {
// Initial window experiment.
congestion_window_ = 10;
}
if (config.HasReceivedConnectionOptions() &&
ContainsQuicTag(config.ReceivedConnectionOptions(), kIW20)) {
// Initial window experiment.
congestion_window_ = 20;
}
if (config.HasReceivedConnectionOptions() &&
ContainsQuicTag(config.ReceivedConnectionOptions(), kIW50)) {
// Initial window experiment.
congestion_window_ = 50;
}
if (config.HasReceivedConnectionOptions() &&
ContainsQuicTag(config.ReceivedConnectionOptions(), kMIN1)) {
// Min CWND experiment.
Expand Down
19 changes: 18 additions & 1 deletion net/quic/congestion_control/tcp_cubic_sender_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -517,12 +517,29 @@ TEST_F(TcpCubicSenderTest, DontTrackAckPackets) {
TEST_F(TcpCubicSenderTest, ConfigureInitialWindow) {
QuicConfig config;

// Verify that kCOPT: kIW10 forces the congestion window to the default of 10.
QuicTagVector options;
options.push_back(kIW03);
QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
sender_->SetFromConfig(config, Perspective::IS_SERVER);
EXPECT_EQ(3u, sender_->congestion_window());

options.clear();
options.push_back(kIW10);
QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
sender_->SetFromConfig(config, Perspective::IS_SERVER);
EXPECT_EQ(10u, sender_->congestion_window());

options.clear();
options.push_back(kIW20);
QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
sender_->SetFromConfig(config, Perspective::IS_SERVER);
EXPECT_EQ(20u, sender_->congestion_window());

options.clear();
options.push_back(kIW50);
QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
sender_->SetFromConfig(config, Perspective::IS_SERVER);
EXPECT_EQ(50u, sender_->congestion_window());
}

TEST_F(TcpCubicSenderTest, ConfigureMinimumWindow) {
Expand Down
7 changes: 0 additions & 7 deletions net/quic/crypto/aead_base_decrypter.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,6 @@ class NET_EXPORT_PRIVATE AeadBaseDecrypter : public QuicDecrypter {
#endif // !defined(USE_OPENSSL)

private:
bool Decrypt(base::StringPiece nonce,
const base::StringPiece& associated_data,
const base::StringPiece& ciphertext,
uint8* output,
size_t* output_length,
size_t max_output_length);

#if defined(USE_OPENSSL)
const EVP_AEAD* const aead_alg_;
#else
Expand Down
50 changes: 19 additions & 31 deletions net/quic/crypto/aead_base_decrypter_nss.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,22 @@ bool AeadBaseDecrypter::SetNoncePrefix(StringPiece nonce_prefix) {
return true;
}

bool AeadBaseDecrypter::Decrypt(StringPiece nonce,
const StringPiece& associated_data,
const StringPiece& ciphertext,
uint8* output,
size_t* output_length,
size_t max_output_length) {
if (ciphertext.length() < auth_tag_size_ ||
nonce.size() != nonce_prefix_size_ + sizeof(QuicPacketSequenceNumber)) {
bool AeadBaseDecrypter::DecryptPacket(QuicPacketSequenceNumber sequence_number,
const StringPiece& associated_data,
const StringPiece& ciphertext,
char* output,
size_t* output_length,
size_t max_output_length) {
if (ciphertext.length() < auth_tag_size_) {
return false;
}

uint8 nonce[sizeof(nonce_prefix_) + sizeof(sequence_number)];
const size_t nonce_size = nonce_prefix_size_ + sizeof(sequence_number);
DCHECK_LE(nonce_size, sizeof(nonce));
memcpy(nonce, nonce_prefix_, nonce_prefix_size_);
memcpy(nonce + nonce_prefix_size_, &sequence_number, sizeof(sequence_number));

// NSS 3.14.x incorrectly requires an output buffer at least as long as
// the ciphertext (NSS bug
// https://bugzilla.mozilla.org/show_bug.cgi?id= 853674). Fortunately
Expand Down Expand Up @@ -93,16 +99,18 @@ bool AeadBaseDecrypter::Decrypt(StringPiece nonce,
}

AeadParams aead_params = {0};
FillAeadParams(nonce, associated_data, auth_tag_size_, &aead_params);
FillAeadParams(StringPiece(reinterpret_cast<char*>(nonce), nonce_size),
associated_data, auth_tag_size_, &aead_params);

SECItem param;
param.type = siBuffer;
param.data = reinterpret_cast<unsigned char*>(&aead_params.data);
param.len = aead_params.len;

unsigned int output_len;
if (pk11_decrypt_(aead_key.get(), aead_mechanism_, &param, output,
&output_len, max_output_length,
if (pk11_decrypt_(aead_key.get(), aead_mechanism_, &param,
reinterpret_cast<uint8*>(output), &output_len,
max_output_length,
reinterpret_cast<const unsigned char*>(ciphertext.data()),
ciphertext.length()) != SECSuccess) {
return false;
Expand All @@ -116,26 +124,6 @@ bool AeadBaseDecrypter::Decrypt(StringPiece nonce,
return true;
}

bool AeadBaseDecrypter::DecryptPacket(QuicPacketSequenceNumber sequence_number,
const StringPiece& associated_data,
const StringPiece& ciphertext,
char* output,
size_t* output_length,
size_t max_output_length) {
if (ciphertext.length() < auth_tag_size_) {
return false;
}

uint8 nonce[sizeof(nonce_prefix_) + sizeof(sequence_number)];
const size_t nonce_size = nonce_prefix_size_ + sizeof(sequence_number);
DCHECK_LE(nonce_size, sizeof(nonce));
memcpy(nonce, nonce_prefix_, nonce_prefix_size_);
memcpy(nonce + nonce_prefix_size_, &sequence_number, sizeof(sequence_number));
return Decrypt(StringPiece(reinterpret_cast<char*>(nonce), nonce_size),
associated_data, ciphertext, reinterpret_cast<uint8*>(output),
output_length, max_output_length);
}

StringPiece AeadBaseDecrypter::GetKey() const {
return StringPiece(reinterpret_cast<const char*>(key_), key_size_);
}
Expand Down
43 changes: 13 additions & 30 deletions net/quic/crypto/aead_base_decrypter_openssl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,32 +76,6 @@ bool AeadBaseDecrypter::SetNoncePrefix(StringPiece nonce_prefix) {
return true;
}

bool AeadBaseDecrypter::Decrypt(StringPiece nonce,
const StringPiece& associated_data,
const StringPiece& ciphertext,
uint8* output,
size_t* output_length,
size_t max_output_length) {
if (ciphertext.length() < auth_tag_size_ ||
nonce.size() != nonce_prefix_size_ + sizeof(QuicPacketSequenceNumber)) {
return false;
}

if (!EVP_AEAD_CTX_open(
ctx_.get(), output, output_length, max_output_length,
reinterpret_cast<const uint8_t*>(nonce.data()), nonce.size(),
reinterpret_cast<const uint8_t*>(ciphertext.data()),
ciphertext.size(),
reinterpret_cast<const uint8_t*>(associated_data.data()),
associated_data.size())) {
// Because QuicFramer does trial decryption, decryption errors are expected
// when encryption level changes. So we don't log decryption errors.
ClearOpenSslErrors();
return false;
}
return true;
}

bool AeadBaseDecrypter::DecryptPacket(QuicPacketSequenceNumber sequence_number,
const StringPiece& associated_data,
const StringPiece& ciphertext,
Expand All @@ -114,12 +88,21 @@ bool AeadBaseDecrypter::DecryptPacket(QuicPacketSequenceNumber sequence_number,

uint8 nonce[sizeof(nonce_prefix_) + sizeof(sequence_number)];
const size_t nonce_size = nonce_prefix_size_ + sizeof(sequence_number);
DCHECK_LE(nonce_size, sizeof(nonce));
memcpy(nonce, nonce_prefix_, nonce_prefix_size_);
memcpy(nonce + nonce_prefix_size_, &sequence_number, sizeof(sequence_number));
return Decrypt(StringPiece(reinterpret_cast<char*>(nonce), nonce_size),
associated_data, ciphertext, reinterpret_cast<uint8*>(output),
output_length, max_output_length);
if (!EVP_AEAD_CTX_open(
ctx_.get(), reinterpret_cast<uint8_t*>(output), output_length,
max_output_length, reinterpret_cast<const uint8_t*>(nonce),
nonce_size, reinterpret_cast<const uint8_t*>(ciphertext.data()),
ciphertext.size(),
reinterpret_cast<const uint8_t*>(associated_data.data()),
associated_data.size())) {
// Because QuicFramer does trial decryption, decryption errors are expected
// when encryption level changes. So we don't log decryption errors.
ClearOpenSslErrors();
return false;
}
return true;
}

StringPiece AeadBaseDecrypter::GetKey() const {
Expand Down
11 changes: 7 additions & 4 deletions net/quic/crypto/aead_base_encrypter.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ class NET_EXPORT_PRIVATE AeadBaseEncrypter : public QuicEncrypter {
// QuicEncrypter implementation
bool SetKey(base::StringPiece key) override;
bool SetNoncePrefix(base::StringPiece nonce_prefix) override;
bool Encrypt(base::StringPiece nonce,
base::StringPiece associated_data,
base::StringPiece plaintext,
unsigned char* output) override;
bool EncryptPacket(QuicPacketSequenceNumber sequence_number,
base::StringPiece associated_data,
base::StringPiece plaintext,
Expand All @@ -59,6 +55,13 @@ class NET_EXPORT_PRIVATE AeadBaseEncrypter : public QuicEncrypter {
base::StringPiece GetKey() const override;
base::StringPiece GetNoncePrefix() const override;

// Necessary so unit tests can explicitly specify a nonce, instead of a
// nonce prefix and sequence number.
bool Encrypt(base::StringPiece nonce,
base::StringPiece associated_data,
base::StringPiece plaintext,
unsigned char* output);

protected:
// Make these constants available to the subclasses so that the subclasses
// can assert at compile time their key_size_ and nonce_prefix_size_ do not
Expand Down
3 changes: 3 additions & 0 deletions net/quic/crypto/crypto_protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@ const QuicTag kQBIC = TAG('Q', 'B', 'I', 'C'); // TCP cubic
const QuicTag kTBBR = TAG('T', 'B', 'B', 'R'); // Reduced Buffer Bloat TCP
const QuicTag kRENO = TAG('R', 'E', 'N', 'O'); // Reno Congestion Control
const QuicTag kBYTE = TAG('B', 'Y', 'T', 'E'); // TCP cubic or reno in bytes
const QuicTag kIW03 = TAG('I', 'W', '0', '3'); // Force ICWND to 3
const QuicTag kIW10 = TAG('I', 'W', '1', '0'); // Force ICWND to 10
const QuicTag kIW20 = TAG('I', 'W', '2', '0'); // Force ICWND to 20
const QuicTag kIW50 = TAG('I', 'W', '5', '0'); // Force ICWND to 50
const QuicTag k1CON = TAG('1', 'C', 'O', 'N'); // Emulate a single connection
const QuicTag kNTLP = TAG('N', 'T', 'L', 'P'); // No tail loss probe
const QuicTag kNCON = TAG('N', 'C', 'O', 'N'); // N Connection Congestion Ctrl
Expand Down
6 changes: 4 additions & 2 deletions net/quic/crypto/crypto_secret_boxer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "net/quic/crypto/aes_128_gcm_12_decrypter.h"
#include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
#include "net/quic/crypto/crypto_protocol.h"
#include "net/quic/crypto/quic_decrypter.h"
#include "net/quic/crypto/quic_encrypter.h"
Expand Down Expand Up @@ -41,7 +43,7 @@ void CryptoSecretBoxer::SetKey(StringPiece key) {
}

string CryptoSecretBoxer::Box(QuicRandom* rand, StringPiece plaintext) const {
scoped_ptr<QuicEncrypter> encrypter(QuicEncrypter::Create(kAESG));
scoped_ptr<Aes128Gcm12Encrypter> encrypter(new Aes128Gcm12Encrypter());
if (!encrypter->SetKey(key_)) {
DLOG(DFATAL) << "CryptoSecretBoxer's encrypter->SetKey failed.";
return string();
Expand Down Expand Up @@ -82,7 +84,7 @@ bool CryptoSecretBoxer::Unbox(StringPiece ciphertext,
memcpy(&sequence_number, nonce.data() + nonce_prefix.size(),
sizeof(sequence_number));

scoped_ptr<QuicDecrypter> decrypter(QuicDecrypter::Create(kAESG));
scoped_ptr<Aes128Gcm12Decrypter> decrypter(new Aes128Gcm12Decrypter());
if (!decrypter->SetKey(key_)) {
DLOG(DFATAL) << "CryptoSecretBoxer's decrypter->SetKey failed.";
return false;
Expand Down
21 changes: 6 additions & 15 deletions net/quic/crypto/null_encrypter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,6 @@ bool NullEncrypter::SetNoncePrefix(StringPiece nonce_prefix) {
return nonce_prefix.empty();
}

bool NullEncrypter::Encrypt(
StringPiece /*nonce*/,
StringPiece associated_data,
StringPiece plaintext,
unsigned char* output) {
string buffer = associated_data.as_string();
plaintext.AppendToString(&buffer);
uint128 hash = QuicUtils::FNV1a_128_Hash(buffer.data(), buffer.length());
QuicUtils::SerializeUint128Short(hash, output);
memcpy(output + GetHashLength(), plaintext.data(), plaintext.size());
return true;
}

bool NullEncrypter::EncryptPacket(QuicPacketSequenceNumber /*sequence_number*/,
StringPiece associated_data,
StringPiece plaintext,
Expand All @@ -44,8 +31,12 @@ bool NullEncrypter::EncryptPacket(QuicPacketSequenceNumber /*sequence_number*/,
if (max_output_length < len) {
return false;
}
Encrypt(StringPiece(), associated_data, plaintext,
reinterpret_cast<unsigned char*>(output));
uint128 hash = QuicUtils::FNV1a_128_Hash_Two(
associated_data.data(), associated_data.size(), plaintext.data(),
plaintext.size());
QuicUtils::SerializeUint128Short(hash,
reinterpret_cast<unsigned char*>(output));
memcpy(output + GetHashLength(), plaintext.data(), plaintext.length());
*output_length = len;
return true;
}
Expand Down
4 changes: 0 additions & 4 deletions net/quic/crypto/null_encrypter.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ class NET_EXPORT_PRIVATE NullEncrypter : public QuicEncrypter {
// QuicEncrypter implementation
bool SetKey(base::StringPiece key) override;
bool SetNoncePrefix(base::StringPiece nonce_prefix) override;
bool Encrypt(base::StringPiece nonce,
base::StringPiece associated_data,
base::StringPiece plaintext,
unsigned char* output) override;
bool EncryptPacket(QuicPacketSequenceNumber sequence_number,
base::StringPiece associated_data,
base::StringPiece plaintext,
Expand Down
4 changes: 2 additions & 2 deletions net/quic/crypto/quic_crypto_server_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,8 @@ class NET_EXPORT_PRIVATE QuicCryptoServerConfig {
// ProcessClientHello processes |client_hello| and decides whether to accept
// or reject the connection. If the connection is to be accepted, |out| is
// set to the contents of the ServerHello, |out_params| is completed and
// QUIC_NO_ERROR is returned. Otherwise |out| is set to be a REJ message and
// an error code is returned.
// QUIC_NO_ERROR is returned. Otherwise |out| is set to be a REJ or SREJ
// message and QUIC_NO_ERROR is returned.
//
// validate_chlo_result: Output from the asynchronous call to
// ValidateClientHello. Contains the client hello message and
Expand Down
10 changes: 0 additions & 10 deletions net/quic/crypto/quic_encrypter.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,6 @@ class NET_EXPORT_PRIVATE QuicEncrypter {
// packet sequence number, even when retransmitting a lost packet.
virtual bool SetNoncePrefix(base::StringPiece nonce_prefix) = 0;

// Encrypt encrypts |plaintext| and writes the ciphertext, plus a MAC over
// both |associated_data| and |plaintext| to |output|, using |nonce| as the
// nonce. |nonce| must be |8+GetNoncePrefixSize()| bytes long and |output|
// must point to a buffer that is at least
// |GetCiphertextSize(plaintext.size()| bytes long.
virtual bool Encrypt(base::StringPiece nonce,
base::StringPiece associated_data,
base::StringPiece plaintext,
unsigned char* output) = 0;

// Returns a newly created QuicData object containing the encrypted
// |plaintext| as well as a MAC over both |plaintext| and |associated_data|,
// or nullptr if there is an error. |sequence_number| is appended to the
Expand Down
Loading

0 comments on commit a4228ea

Please sign in to comment.