diff options
author | rogerta@chromium.org <rogerta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-22 14:47:50 +0000 |
---|---|---|
committer | rogerta@chromium.org <rogerta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-22 14:47:50 +0000 |
commit | af806e6d9e18cdd223c76db4af45af3559e75245 (patch) | |
tree | 21c7badd804adacb46558fc73d0f953f49614c54 /net/quic/crypto/aes_128_gcm_encrypter_openssl.cc | |
parent | c85a2af7a310db435ddb5fd849a7de56b1b49c79 (diff) | |
download | chromium_src-af806e6d9e18cdd223c76db4af45af3559e75245.zip chromium_src-af806e6d9e18cdd223c76db4af45af3559e75245.tar.gz chromium_src-af806e6d9e18cdd223c76db4af45af3559e75245.tar.bz2 |
Revert 201501 "Land Recent QUIC changes."
Broke chromium.chrome build:
../../net/quic/test_tools/crypto_test_utils.cc:400:error: 'v' may be used uninitialized in this function
> Land Recent QUIC changes.
>
> Use example.com as test hostname.
>
> Merge internal change: 46048925
>
> Only updating the time of last packet once we've done our best to verify packet validity.
>
> Merge internal change: 46044184
>
> Improve logging behavior in quic_connection.h.
>
> Merge internal change: 46033559
>
> Moving the public flags to the beginning of the header in preparation for variable length guids.
>
> Merge internal change: 45980153
>
> QUIC: change the GCM tag size to 12 bytes.
>
> Merge internal change: 45973625
>
> QUIC: add some crypto tests.
>
> The client code tries to be correct, which can hamper some tests that wish to
> send invalid requests.
>
> This CL contains some utilities for constructing arbitrary handshake messages
> and some tests that exercise the server crypto code.
>
> Merge internal change: 45972782
>
> Not allowing retransmissions to affect client timeouts. Fixes a serious
> bug where if client vanishes and we have unacked packets, the connection
> could live on forever.
>
> Merge internal change: 45935953
>
> Address wtc's comments on cl/44272981.
>
> Merge internal change: 45917323
>
> QUIC: don't CHECK when QUIC is enabled without any certificates loaded.
>
> Without certificates we don't have any key material for the source-address
> token nor server config and so QUIC isn't setup at server load time. However,
> if QUIC is enabled anyway then it'll crash.
>
> This change removes the CHECK and has every crypto handshake fail instead.
>
> (I have tests for the recent SNI change pending, into which a test for this
> will fall nicely, hopefully this afternoon. But I'm prioritising this change
> for now rather than waiting for the test CL to land.)
>
> Merge internal change: 45914344
>
> Merging cleanup changes from chromium
>
> Merge internal change: 45797529
>
> QUIC: pad client hello messages and require padding on the server.
>
> This reduces any amplification factor that an attacker might get from us. I've
> picked a minimum size of 512 bytes out of thin air.
>
> Satyam has a change pending that bumps the version to 2 so I've omitted that here.
>
> Merge internal change: 45779287
>
> QUIC: small fixes
>
> * Don't send invalid SNIs as a client.
> * Don't require an SNI as a server.
> * Don't ignore client hello processing errors.
>
> Merge internal change: 45774287
>
> QUIC - set QUIC max stream per connections based on SNI.
>
> Merge internal change: 45656436
>
> - Enabled EndToEnd's Timeout unittest.
> - Ported IsValidSNI and NormalizeHostname from internal code.
>
> R=rch@chromium.org
>
> Review URL: https://chromiumcodereview.appspot.com/15385004
TBR=rtenneti@chromium.org
Review URL: https://codereview.chromium.org/15737008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@201516 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/quic/crypto/aes_128_gcm_encrypter_openssl.cc')
-rw-r--r-- | net/quic/crypto/aes_128_gcm_encrypter_openssl.cc | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/net/quic/crypto/aes_128_gcm_encrypter_openssl.cc b/net/quic/crypto/aes_128_gcm_encrypter_openssl.cc new file mode 100644 index 0000000..b00dec8 --- /dev/null +++ b/net/quic/crypto/aes_128_gcm_encrypter_openssl.cc @@ -0,0 +1,158 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/quic/crypto/aes_128_gcm_encrypter.h" + +#include <openssl/evp.h> +#include <string.h> + +#include "base/memory/scoped_ptr.h" +#include "net/quic/crypto/scoped_evp_cipher_ctx.h" + +using base::StringPiece; + +namespace net { + +namespace { + +const size_t kKeySize = 16; +const size_t kNoncePrefixSize = 4; +const size_t kAuthTagSize = 16; + +} // namespace + +Aes128GcmEncrypter::Aes128GcmEncrypter() { +} + +// static +bool Aes128GcmEncrypter::IsSupported() { return true; } + +bool Aes128GcmEncrypter::SetKey(StringPiece key) { + DCHECK_EQ(key.size(), sizeof(key_)); + if (key.size() != sizeof(key_)) { + return false; + } + memcpy(key_, key.data(), key.size()); + return true; +} + +bool Aes128GcmEncrypter::SetNoncePrefix(StringPiece nonce_prefix) { + DCHECK_EQ(nonce_prefix.size(), kNoncePrefixSize); + if (nonce_prefix.size() != kNoncePrefixSize) { + return false; + } + memcpy(nonce_, nonce_prefix.data(), nonce_prefix.size()); + return true; +} + +bool Aes128GcmEncrypter::Encrypt(StringPiece nonce, + StringPiece associated_data, + StringPiece plaintext, + unsigned char* output) { + // |output_len| is passed to an OpenSSL function to receive the output + // length. + int output_len; + + if (nonce.size() != kNoncePrefixSize + sizeof(QuicPacketSequenceNumber)) { + return false; + } + + ScopedEVPCipherCtx ctx; + + // Set the cipher type and the key. The IV (nonce) is set below. + if (EVP_EncryptInit_ex(ctx.get(), EVP_aes_128_gcm(), NULL, key_, NULL) == 0) { + return false; + } + + // Set the IV (nonce) length. + if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IVLEN, nonce.size(), + NULL) == 0) { + return false; + } + // Set the IV (nonce). + if (EVP_EncryptInit_ex( + ctx.get(), NULL, NULL, NULL, + reinterpret_cast<const unsigned char*>(nonce.data())) == 0) { + return false; + } + + // If we pass a NULL, zero-length associated data to OpenSSL then it breaks. + // Thus we only set non-empty associated data. + if (!associated_data.empty()) { + // Set the associated data. The second argument (output buffer) must be + // NULL. + if (EVP_EncryptUpdate( + ctx.get(), NULL, &output_len, + reinterpret_cast<const unsigned char*>(associated_data.data()), + associated_data.size()) == 0) { + return false; + } + } + + if (EVP_EncryptUpdate( + ctx.get(), output, &output_len, + reinterpret_cast<const unsigned char*>(plaintext.data()), + plaintext.size()) == 0) { + return false; + } + output += output_len; + + if (EVP_EncryptFinal_ex(ctx.get(), output, &output_len) == 0) { + return false; + } + output += output_len; + + if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, kAuthTagSize, + output) == 0) { + return false; + } + + return true; +} + +QuicData* Aes128GcmEncrypter::EncryptPacket( + QuicPacketSequenceNumber sequence_number, + StringPiece associated_data, + StringPiece plaintext) { + COMPILE_ASSERT(sizeof(nonce_) == kNoncePrefixSize + sizeof(sequence_number), + incorrect_nonce_size); + memcpy(nonce_ + kNoncePrefixSize, &sequence_number, sizeof(sequence_number)); + + size_t ciphertext_size = GetCiphertextSize(plaintext.length()); + scoped_ptr<char[]> ciphertext(new char[ciphertext_size]); + + if (!Encrypt(StringPiece(reinterpret_cast<char*>(nonce_), sizeof(nonce_)), + associated_data, plaintext, + reinterpret_cast<unsigned char*>(ciphertext.get()))) { + return NULL; + } + + return new QuicData(ciphertext.release(), ciphertext_size, true); +} + +size_t Aes128GcmEncrypter::GetKeySize() const { return kKeySize; } + +size_t Aes128GcmEncrypter::GetNoncePrefixSize() const { + return kNoncePrefixSize; +} + +size_t Aes128GcmEncrypter::GetMaxPlaintextSize(size_t ciphertext_size) const { + return ciphertext_size - kAuthTagSize; +} + +// An AEAD_AES_128_GCM ciphertext is exactly 16 bytes longer than its +// corresponding plaintext. +size_t Aes128GcmEncrypter::GetCiphertextSize(size_t plaintext_size) const { + return plaintext_size + kAuthTagSize; +} + +StringPiece Aes128GcmEncrypter::GetKey() const { + return StringPiece(reinterpret_cast<const char*>(key_), sizeof(key_)); +} + +StringPiece Aes128GcmEncrypter::GetNoncePrefix() const { + return StringPiece(reinterpret_cast<const char*>(nonce_), kNoncePrefixSize); +} + +} // namespace net |