summaryrefslogtreecommitdiffstats
path: root/net/quic/crypto/aes_128_gcm_encrypter_openssl.cc
diff options
context:
space:
mode:
authorrogerta@chromium.org <rogerta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-22 14:47:50 +0000
committerrogerta@chromium.org <rogerta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-22 14:47:50 +0000
commitaf806e6d9e18cdd223c76db4af45af3559e75245 (patch)
tree21c7badd804adacb46558fc73d0f953f49614c54 /net/quic/crypto/aes_128_gcm_encrypter_openssl.cc
parentc85a2af7a310db435ddb5fd849a7de56b1b49c79 (diff)
downloadchromium_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.cc158
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