diff options
Diffstat (limited to 'chromium/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc')
-rw-r--r-- | chromium/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc | 164 |
1 files changed, 7 insertions, 157 deletions
diff --git a/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc b/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc index 394971a7382..6489528fd37 100644 --- a/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc +++ b/chromium/net/quic/crypto/aes_128_gcm_12_encrypter_openssl.cc @@ -4,13 +4,7 @@ #include "net/quic/crypto/aes_128_gcm_12_encrypter.h" -#include <openssl/err.h> #include <openssl/evp.h> -#include <string.h> - -#include "base/memory/scoped_ptr.h" - -using base::StringPiece; namespace net { @@ -18,161 +12,17 @@ namespace { const size_t kKeySize = 16; const size_t kNoncePrefixSize = 4; -const size_t kAESNonceSize = 12; - -void ClearOpenSslErrors() { -#ifdef NDEBUG - while (ERR_get_error()) {} -#else - while (long error = ERR_get_error()) { - char buf[120]; - ERR_error_string_n(error, buf, arraysize(buf)); - DLOG(ERROR) << "OpenSSL error: " << buf; - } -#endif -} } // namespace -Aes128Gcm12Encrypter::Aes128Gcm12Encrypter() {} - -Aes128Gcm12Encrypter::~Aes128Gcm12Encrypter() {} - -bool Aes128Gcm12Encrypter::SetKey(StringPiece key) { - DCHECK_EQ(key.size(), sizeof(key_)); - if (key.size() != sizeof(key_)) { - return false; - } - memcpy(key_, key.data(), key.size()); - - // Set the cipher type and the key. - if (EVP_EncryptInit_ex(ctx_.get(), EVP_aes_128_gcm(), NULL, key_, - NULL) == 0) { - ClearOpenSslErrors(); - return false; - } - - // Set the IV (nonce) length. - if (EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_GCM_SET_IVLEN, kAESNonceSize, - NULL) == 0) { - ClearOpenSslErrors(); - return false; - } - - return true; -} - -bool Aes128Gcm12Encrypter::SetNoncePrefix(StringPiece nonce_prefix) { - DCHECK_EQ(nonce_prefix.size(), kNoncePrefixSize); - if (nonce_prefix.size() != kNoncePrefixSize) { - return false; - } - COMPILE_ASSERT(sizeof(nonce_prefix_) == kNoncePrefixSize, bad_nonce_length); - memcpy(nonce_prefix_, nonce_prefix.data(), nonce_prefix.size()); - return true; +Aes128Gcm12Encrypter::Aes128Gcm12Encrypter() + : AeadBaseEncrypter(EVP_aead_aes_128_gcm(), kKeySize, kAuthTagSize, + kNoncePrefixSize) { + COMPILE_ASSERT(kKeySize <= kMaxKeySize, key_size_too_big); + COMPILE_ASSERT(kNoncePrefixSize <= kMaxNoncePrefixSize, + nonce_prefix_size_too_big); } -bool Aes128Gcm12Encrypter::Encrypt(StringPiece nonce, - StringPiece associated_data, - StringPiece plaintext, - unsigned char* output) { - if (nonce.size() != kNoncePrefixSize + sizeof(QuicPacketSequenceNumber)) { - return false; - } - - // Set the IV (nonce). - if (EVP_EncryptInit_ex( - ctx_.get(), NULL, NULL, NULL, - reinterpret_cast<const unsigned char*>(nonce.data())) == 0) { - ClearOpenSslErrors(); - 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. - int unused_len; - if (EVP_EncryptUpdate( - ctx_.get(), NULL, &unused_len, - reinterpret_cast<const unsigned char*>(associated_data.data()), - associated_data.size()) == 0) { - ClearOpenSslErrors(); - return false; - } - } - - int len; - if (EVP_EncryptUpdate( - ctx_.get(), output, &len, - reinterpret_cast<const unsigned char*>(plaintext.data()), - plaintext.size()) == 0) { - ClearOpenSslErrors(); - return false; - } - output += len; - - if (EVP_EncryptFinal_ex(ctx_.get(), output, &len) == 0) { - ClearOpenSslErrors(); - return false; - } - output += len; - - if (EVP_CIPHER_CTX_ctrl(ctx_.get(), EVP_CTRL_GCM_GET_TAG, kAuthTagSize, - output) == 0) { - ClearOpenSslErrors(); - return false; - } - - return true; -} - -QuicData* Aes128Gcm12Encrypter::EncryptPacket( - QuicPacketSequenceNumber sequence_number, - StringPiece associated_data, - StringPiece plaintext) { - size_t ciphertext_size = GetCiphertextSize(plaintext.length()); - scoped_ptr<char[]> ciphertext(new char[ciphertext_size]); - - // TODO(ianswett): Introduce a check to ensure that we don't encrypt with the - // same sequence number twice. - uint8 nonce[kNoncePrefixSize + sizeof(sequence_number)]; - COMPILE_ASSERT(sizeof(nonce) == kAESNonceSize, bad_sequence_number_size); - memcpy(nonce, nonce_prefix_, kNoncePrefixSize); - memcpy(nonce + kNoncePrefixSize, &sequence_number, sizeof(sequence_number)); - 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 Aes128Gcm12Encrypter::GetKeySize() const { return kKeySize; } - -size_t Aes128Gcm12Encrypter::GetNoncePrefixSize() const { - return kNoncePrefixSize; -} - -size_t Aes128Gcm12Encrypter::GetMaxPlaintextSize(size_t ciphertext_size) const { - return ciphertext_size - kAuthTagSize; -} - -// An AEAD_AES_128_GCM_12 ciphertext is exactly 12 bytes longer than its -// corresponding plaintext. -size_t Aes128Gcm12Encrypter::GetCiphertextSize(size_t plaintext_size) const { - return plaintext_size + kAuthTagSize; -} - -StringPiece Aes128Gcm12Encrypter::GetKey() const { - return StringPiece(reinterpret_cast<const char*>(key_), sizeof(key_)); -} - -StringPiece Aes128Gcm12Encrypter::GetNoncePrefix() const { - return StringPiece(reinterpret_cast<const char*>(nonce_prefix_), - kNoncePrefixSize); -} +Aes128Gcm12Encrypter::~Aes128Gcm12Encrypter() {} } // namespace net |