From 22de42fecbdc7d132c086dec7744033ff20af55e Mon Sep 17 00:00:00 2001 From: svaldez Date: Thu, 21 Apr 2016 12:42:22 -0700 Subject: [PATCH] Rename crypto/ *_openssl files With the removal of most of the NSS code, we no longer need to split up code between NSS and OpenSSL implementations. BUG=604728 Review URL: https://codereview.chromium.org/1909513003 Cr-Commit-Position: refs/heads/master@{#388856} --- .../certificate_reporting/error_reporter.cc | 2 +- crypto/BUILD.gn | 19 +- crypto/{aead_openssl.cc => aead.cc} | 2 +- crypto/{aead_openssl.h => aead.h} | 3 +- ...d_openssl_unittest.cc => aead_unittest.cc} | 2 +- crypto/crypto.gyp | 2 +- crypto/crypto.gypi | 17 +- .../{curve25519_openssl.cc => curve25519.cc} | 0 ...ivate_key_openssl.cc => ec_private_key.cc} | 0 crypto/encryptor.cc | 166 +++++++++++++++- crypto/encryptor.h | 2 +- crypto/encryptor_openssl.cc | 178 ------------------ ...vate_key_openssl.cc => rsa_private_key.cc} | 0 ...{secure_hash_openssl.cc => secure_hash.cc} | 12 +- ...reator_openssl.cc => signature_creator.cc} | 0 ...ifier_openssl.cc => signature_verifier.cc} | 0 16 files changed, 194 insertions(+), 211 deletions(-) rename crypto/{aead_openssl.cc => aead.cc} (99%) rename crypto/{aead_openssl.h => aead.h} (92%) rename crypto/{aead_openssl_unittest.cc => aead_unittest.cc} (97%) rename crypto/{curve25519_openssl.cc => curve25519.cc} (100%) rename crypto/{ec_private_key_openssl.cc => ec_private_key.cc} (100%) delete mode 100644 crypto/encryptor_openssl.cc rename crypto/{rsa_private_key_openssl.cc => rsa_private_key.cc} (100%) rename crypto/{secure_hash_openssl.cc => secure_hash.cc} (81%) rename crypto/{signature_creator_openssl.cc => signature_creator.cc} (100%) rename crypto/{signature_verifier_openssl.cc => signature_verifier.cc} (100%) diff --git a/components/certificate_reporting/error_reporter.cc b/components/certificate_reporting/error_reporter.cc index 9c8bb839c72d05..f783260753b1fc 100644 --- a/components/certificate_reporting/error_reporter.cc +++ b/components/certificate_reporting/error_reporter.cc @@ -10,7 +10,7 @@ #include "base/logging.h" #include "components/certificate_reporting/encrypted_cert_logger.pb.h" -#include "crypto/aead_openssl.h" +#include "crypto/aead.h" #include "crypto/curve25519.h" #include "crypto/hkdf.h" #include "crypto/random.h" diff --git a/crypto/BUILD.gn b/crypto/BUILD.gn index 2b868936b85fa0..d42065fdab0784 100644 --- a/crypto/BUILD.gn +++ b/crypto/BUILD.gn @@ -8,8 +8,8 @@ import("//testing/test.gni") component("crypto") { output_name = "crcrypto" # Avoid colliding with OpenSSL's libcrypto. sources = [ - "aead_openssl.cc", - "aead_openssl.h", + "aead.cc", + "aead.h", "apple_keychain.h", "apple_keychain_ios.mm", "apple_keychain_mac.mm", @@ -19,17 +19,16 @@ component("crypto") { "crypto_export.h", "cssm_init.cc", "cssm_init.h", + "curve25519.cc", "curve25519.h", - "curve25519_openssl.cc", + "ec_private_key.cc", "ec_private_key.h", - "ec_private_key_openssl.cc", "ec_signature_creator.cc", "ec_signature_creator.h", "ec_signature_creator_impl.h", "ec_signature_creator_openssl.cc", "encryptor.cc", "encryptor.h", - "encryptor_openssl.cc", "hkdf.cc", "hkdf.h", "hmac.cc", @@ -59,20 +58,20 @@ component("crypto") { "p224_spake.h", "random.cc", "random.h", + "rsa_private_key.cc", "rsa_private_key.h", - "rsa_private_key_openssl.cc", "scoped_capi_types.h", "scoped_nss_types.h", + "secure_hash.cc", "secure_hash.h", - "secure_hash_openssl.cc", "secure_util.cc", "secure_util.h", "sha2.cc", "sha2.h", + "signature_creator.cc", "signature_creator.h", - "signature_creator_openssl.cc", + "signature_verifier.cc", "signature_verifier.h", - "signature_verifier_openssl.cc", "symmetric_key.h", "symmetric_key_openssl.cc", "third_party/nss/chromium-sha256.h", @@ -165,7 +164,7 @@ if (false && is_win) { test("crypto_unittests") { sources = [ - "aead_openssl_unittest.cc", + "aead_unittest.cc", "curve25519_unittest.cc", "ec_private_key_unittest.cc", "ec_signature_creator_unittest.cc", diff --git a/crypto/aead_openssl.cc b/crypto/aead.cc similarity index 99% rename from crypto/aead_openssl.cc rename to crypto/aead.cc index 8ad05dca1660ac..1be24cdb88d846 100644 --- a/crypto/aead_openssl.cc +++ b/crypto/aead.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "crypto/aead_openssl.h" +#include "crypto/aead.h" #include #include diff --git a/crypto/aead_openssl.h b/crypto/aead.h similarity index 92% rename from crypto/aead_openssl.h rename to crypto/aead.h index 3ba60419a30f7a..fa96eab9eb9f13 100644 --- a/crypto/aead_openssl.h +++ b/crypto/aead.h @@ -14,8 +14,7 @@ struct evp_aead_st; namespace crypto { -// This class exposes the AES-128-CTR-HMAC-SHA256 AEAD, currently only -// for OpenSSL builds. +// This class exposes the AES-128-CTR-HMAC-SHA256 AEAD. class CRYPTO_EXPORT Aead { public: enum AeadAlgorithm { AES_128_CTR_HMAC_SHA256 }; diff --git a/crypto/aead_openssl_unittest.cc b/crypto/aead_unittest.cc similarity index 97% rename from crypto/aead_openssl_unittest.cc rename to crypto/aead_unittest.cc index 395e15a35a16be..3218b43c047e99 100644 --- a/crypto/aead_openssl_unittest.cc +++ b/crypto/aead_unittest.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "crypto/aead_openssl.h" +#include "crypto/aead.h" #include diff --git a/crypto/crypto.gyp b/crypto/crypto.gyp index 9edbe3560260a5..fd411bb3af09ab 100644 --- a/crypto/crypto.gyp +++ b/crypto/crypto.gyp @@ -107,7 +107,7 @@ 'target_name': 'crypto_unittests', 'type': 'executable', 'sources': [ - 'aead_openssl_unittest.cc', + 'aead_unittest.cc', 'curve25519_unittest.cc', 'ec_private_key_unittest.cc', 'ec_signature_creator_unittest.cc', diff --git a/crypto/crypto.gypi b/crypto/crypto.gypi index 748f4a90f6a11d..43d43066194320 100644 --- a/crypto/crypto.gypi +++ b/crypto/crypto.gypi @@ -25,8 +25,8 @@ # NOTE: all transitive dependencies of HMAC on windows need # to be placed in the source list above. '<@(hmac_win64_related_sources)', - 'aead_openssl.cc', - 'aead_openssl.h', + 'aead.cc', + 'aead.h', 'apple_keychain.h', 'apple_keychain_ios.mm', 'apple_keychain_mac.mm', @@ -36,17 +36,16 @@ 'crypto_export.h', 'cssm_init.cc', 'cssm_init.h', + 'curve25519.cc', 'curve25519.h', - 'curve25519_openssl.cc', + 'ec_private_key.cc', 'ec_private_key.h', - 'ec_private_key_openssl.cc', 'ec_signature_creator.cc', 'ec_signature_creator.h', 'ec_signature_creator_impl.h', 'ec_signature_creator_openssl.cc', 'encryptor.cc', 'encryptor.h', - 'encryptor_openssl.cc', 'hkdf.cc', 'hkdf.h', 'hmac_openssl.cc', @@ -72,18 +71,18 @@ 'p224.h', 'random.h', 'random.cc', + 'rsa_private_key.cc', 'rsa_private_key.h', - 'rsa_private_key_openssl.cc', 'scoped_capi_types.h', 'scoped_nss_types.h', + 'secure_hash.cc', 'secure_hash.h', - 'secure_hash_openssl.cc', 'sha2.cc', 'sha2.h', + 'signature_creator.cc', 'signature_creator.h', - 'signature_creator_openssl.cc', + 'signature_verifier.cc', 'signature_verifier.h', - 'signature_verifier_openssl.cc', 'symmetric_key_openssl.cc', ], 'nacl_win64_sources': [ diff --git a/crypto/curve25519_openssl.cc b/crypto/curve25519.cc similarity index 100% rename from crypto/curve25519_openssl.cc rename to crypto/curve25519.cc diff --git a/crypto/ec_private_key_openssl.cc b/crypto/ec_private_key.cc similarity index 100% rename from crypto/ec_private_key_openssl.cc rename to crypto/ec_private_key.cc diff --git a/crypto/encryptor.cc b/crypto/encryptor.cc index 7872774e301c69..a9f9a9d5dcea15 100644 --- a/crypto/encryptor.cc +++ b/crypto/encryptor.cc @@ -4,14 +4,48 @@ #include "crypto/encryptor.h" +#include +#include #include #include #include "base/logging.h" +#include "base/strings/string_util.h" #include "base/sys_byteorder.h" +#include "crypto/openssl_util.h" +#include "crypto/symmetric_key.h" namespace crypto { +namespace { + +const EVP_CIPHER* GetCipherForKey(SymmetricKey* key) { + switch (key->key().length()) { + case 16: return EVP_aes_128_cbc(); + case 32: return EVP_aes_256_cbc(); + default: return NULL; + } +} + +// On destruction this class will cleanup the ctx, and also clear the OpenSSL +// ERR stack as a convenience. +class ScopedCipherCTX { + public: + explicit ScopedCipherCTX() { + EVP_CIPHER_CTX_init(&ctx_); + } + ~ScopedCipherCTX() { + EVP_CIPHER_CTX_cleanup(&ctx_); + ClearOpenSSLERRStack(FROM_HERE); + } + EVP_CIPHER_CTX* get() { return &ctx_; } + + private: + EVP_CIPHER_CTX ctx_; +}; + +} // namespace + ///////////////////////////////////////////////////////////////////////////// // Encyptor::Counter Implementation. Encryptor::Counter::Counter(const base::StringPiece& counter) { @@ -48,7 +82,50 @@ size_t Encryptor::Counter::GetLengthInBytes() const { } ///////////////////////////////////////////////////////////////////////////// -// Partial Encryptor Implementation. +// Encryptor Implementation. + +Encryptor::Encryptor() + : key_(NULL), + mode_(CBC) { +} + +Encryptor::~Encryptor() { +} + +bool Encryptor::Init(SymmetricKey* key, + Mode mode, + const base::StringPiece& iv) { + DCHECK(key); + DCHECK(mode == CBC || mode == CTR); + + EnsureOpenSSLInit(); + if (mode == CBC && iv.size() != AES_BLOCK_SIZE) + return false; + + if (GetCipherForKey(key) == NULL) + return false; + + key_ = key; + mode_ = mode; + iv.CopyToString(&iv_); + return true; +} + +bool Encryptor::Encrypt(const base::StringPiece& plaintext, + std::string* ciphertext) { + CHECK(!plaintext.empty() || (mode_ == CBC)); + return (mode_ == CTR) ? + CryptCTR(true, plaintext, ciphertext) : + Crypt(true, plaintext, ciphertext); +} + +bool Encryptor::Decrypt(const base::StringPiece& ciphertext, + std::string* plaintext) { + CHECK(!ciphertext.empty()); + return (mode_ == CTR) ? + CryptCTR(false, ciphertext, plaintext) : + Crypt(false, ciphertext, plaintext); +} bool Encryptor::SetCounter(const base::StringPiece& counter) { if (mode_ != CTR) @@ -97,4 +174,91 @@ void Encryptor::MaskMessage(const void* plaintext, ciphertext_ptr[i] = plaintext_ptr[i] ^ mask_ptr[i]; } +bool Encryptor::Crypt(bool do_encrypt, + const base::StringPiece& input, + std::string* output) { + DCHECK(key_); // Must call Init() before En/De-crypt. + // Work on the result in a local variable, and then only transfer it to + // |output| on success to ensure no partial data is returned. + std::string result; + output->clear(); + + const EVP_CIPHER* cipher = GetCipherForKey(key_); + DCHECK(cipher); // Already handled in Init(); + + const std::string& key = key_->key(); + DCHECK_EQ(EVP_CIPHER_iv_length(cipher), iv_.length()); + DCHECK_EQ(EVP_CIPHER_key_length(cipher), key.length()); + + ScopedCipherCTX ctx; + if (!EVP_CipherInit_ex( + ctx.get(), cipher, NULL, reinterpret_cast(key.data()), + reinterpret_cast(iv_.data()), do_encrypt)) + return false; + + // When encrypting, add another block size of space to allow for any padding. + const size_t output_size = input.size() + (do_encrypt ? iv_.size() : 0); + CHECK_GT(output_size, 0u); + CHECK_GT(output_size + 1, input.size()); + uint8_t* out_ptr = + reinterpret_cast(base::WriteInto(&result, output_size + 1)); + int out_len; + if (!EVP_CipherUpdate(ctx.get(), out_ptr, &out_len, + reinterpret_cast(input.data()), + input.length())) + return false; + + // Write out the final block plus padding (if any) to the end of the data + // just written. + int tail_len; + if (!EVP_CipherFinal_ex(ctx.get(), out_ptr + out_len, &tail_len)) + return false; + + out_len += tail_len; + DCHECK_LE(out_len, static_cast(output_size)); + result.resize(out_len); + + output->swap(result); + return true; +} + +bool Encryptor::CryptCTR(bool do_encrypt, + const base::StringPiece& input, + std::string* output) { + if (!counter_.get()) { + LOG(ERROR) << "Counter value not set in CTR mode."; + return false; + } + + AES_KEY aes_key; + if (AES_set_encrypt_key(reinterpret_cast(key_->key().data()), + key_->key().size() * 8, &aes_key) != 0) { + return false; + } + + const size_t out_size = input.size(); + CHECK_GT(out_size, 0u); + CHECK_GT(out_size + 1, input.size()); + + std::string result; + uint8_t* out_ptr = + reinterpret_cast(base::WriteInto(&result, out_size + 1)); + + uint8_t ivec[AES_BLOCK_SIZE] = { 0 }; + uint8_t ecount_buf[AES_BLOCK_SIZE] = { 0 }; + unsigned int block_offset = 0; + + counter_->Write(ivec); + + AES_ctr128_encrypt(reinterpret_cast(input.data()), out_ptr, + input.size(), &aes_key, ivec, ecount_buf, &block_offset); + + // AES_ctr128_encrypt() updates |ivec|. Update the |counter_| here. + SetCounter(base::StringPiece(reinterpret_cast(ivec), + AES_BLOCK_SIZE)); + + output->swap(result); + return true; +} + } // namespace crypto diff --git a/crypto/encryptor.h b/crypto/encryptor.h index f5a1031a50a997..4b6745ef0fd278 100644 --- a/crypto/encryptor.h +++ b/crypto/encryptor.h @@ -51,7 +51,7 @@ class CRYPTO_EXPORT Encryptor { }; Encryptor(); - virtual ~Encryptor(); + ~Encryptor(); // Initializes the encryptor using |key| and |iv|. Returns false if either the // key or the initialization vector cannot be used. diff --git a/crypto/encryptor_openssl.cc b/crypto/encryptor_openssl.cc deleted file mode 100644 index 238b2e0d540315..00000000000000 --- a/crypto/encryptor_openssl.cc +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright (c) 2011 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 "crypto/encryptor.h" - -#include -#include -#include -#include - -#include "base/logging.h" -#include "base/strings/string_util.h" -#include "crypto/openssl_util.h" -#include "crypto/symmetric_key.h" - -namespace crypto { - -namespace { - -const EVP_CIPHER* GetCipherForKey(SymmetricKey* key) { - switch (key->key().length()) { - case 16: return EVP_aes_128_cbc(); - case 32: return EVP_aes_256_cbc(); - default: return NULL; - } -} - -// On destruction this class will cleanup the ctx, and also clear the OpenSSL -// ERR stack as a convenience. -class ScopedCipherCTX { - public: - explicit ScopedCipherCTX() { - EVP_CIPHER_CTX_init(&ctx_); - } - ~ScopedCipherCTX() { - EVP_CIPHER_CTX_cleanup(&ctx_); - ClearOpenSSLERRStack(FROM_HERE); - } - EVP_CIPHER_CTX* get() { return &ctx_; } - - private: - EVP_CIPHER_CTX ctx_; -}; - -} // namespace - -Encryptor::Encryptor() - : key_(NULL), - mode_(CBC) { -} - -Encryptor::~Encryptor() { -} - -bool Encryptor::Init(SymmetricKey* key, - Mode mode, - const base::StringPiece& iv) { - DCHECK(key); - DCHECK(mode == CBC || mode == CTR); - - EnsureOpenSSLInit(); - if (mode == CBC && iv.size() != AES_BLOCK_SIZE) - return false; - - if (GetCipherForKey(key) == NULL) - return false; - - key_ = key; - mode_ = mode; - iv.CopyToString(&iv_); - return true; -} - -bool Encryptor::Encrypt(const base::StringPiece& plaintext, - std::string* ciphertext) { - CHECK(!plaintext.empty() || (mode_ == CBC)); - return (mode_ == CTR) ? - CryptCTR(true, plaintext, ciphertext) : - Crypt(true, plaintext, ciphertext); -} - -bool Encryptor::Decrypt(const base::StringPiece& ciphertext, - std::string* plaintext) { - CHECK(!ciphertext.empty()); - return (mode_ == CTR) ? - CryptCTR(false, ciphertext, plaintext) : - Crypt(false, ciphertext, plaintext); -} - -bool Encryptor::Crypt(bool do_encrypt, - const base::StringPiece& input, - std::string* output) { - DCHECK(key_); // Must call Init() before En/De-crypt. - // Work on the result in a local variable, and then only transfer it to - // |output| on success to ensure no partial data is returned. - std::string result; - output->clear(); - - const EVP_CIPHER* cipher = GetCipherForKey(key_); - DCHECK(cipher); // Already handled in Init(); - - const std::string& key = key_->key(); - DCHECK_EQ(EVP_CIPHER_iv_length(cipher), iv_.length()); - DCHECK_EQ(EVP_CIPHER_key_length(cipher), key.length()); - - ScopedCipherCTX ctx; - if (!EVP_CipherInit_ex( - ctx.get(), cipher, NULL, reinterpret_cast(key.data()), - reinterpret_cast(iv_.data()), do_encrypt)) - return false; - - // When encrypting, add another block size of space to allow for any padding. - const size_t output_size = input.size() + (do_encrypt ? iv_.size() : 0); - CHECK_GT(output_size, 0u); - CHECK_GT(output_size + 1, input.size()); - uint8_t* out_ptr = - reinterpret_cast(base::WriteInto(&result, output_size + 1)); - int out_len; - if (!EVP_CipherUpdate(ctx.get(), out_ptr, &out_len, - reinterpret_cast(input.data()), - input.length())) - return false; - - // Write out the final block plus padding (if any) to the end of the data - // just written. - int tail_len; - if (!EVP_CipherFinal_ex(ctx.get(), out_ptr + out_len, &tail_len)) - return false; - - out_len += tail_len; - DCHECK_LE(out_len, static_cast(output_size)); - result.resize(out_len); - - output->swap(result); - return true; -} - -bool Encryptor::CryptCTR(bool do_encrypt, - const base::StringPiece& input, - std::string* output) { - if (!counter_.get()) { - LOG(ERROR) << "Counter value not set in CTR mode."; - return false; - } - - AES_KEY aes_key; - if (AES_set_encrypt_key(reinterpret_cast(key_->key().data()), - key_->key().size() * 8, &aes_key) != 0) { - return false; - } - - const size_t out_size = input.size(); - CHECK_GT(out_size, 0u); - CHECK_GT(out_size + 1, input.size()); - - std::string result; - uint8_t* out_ptr = - reinterpret_cast(base::WriteInto(&result, out_size + 1)); - - uint8_t ivec[AES_BLOCK_SIZE] = { 0 }; - uint8_t ecount_buf[AES_BLOCK_SIZE] = { 0 }; - unsigned int block_offset = 0; - - counter_->Write(ivec); - - AES_ctr128_encrypt(reinterpret_cast(input.data()), out_ptr, - input.size(), &aes_key, ivec, ecount_buf, &block_offset); - - // AES_ctr128_encrypt() updates |ivec|. Update the |counter_| here. - SetCounter(base::StringPiece(reinterpret_cast(ivec), - AES_BLOCK_SIZE)); - - output->swap(result); - return true; -} - -} // namespace crypto diff --git a/crypto/rsa_private_key_openssl.cc b/crypto/rsa_private_key.cc similarity index 100% rename from crypto/rsa_private_key_openssl.cc rename to crypto/rsa_private_key.cc diff --git a/crypto/secure_hash_openssl.cc b/crypto/secure_hash.cc similarity index 81% rename from crypto/secure_hash_openssl.cc rename to crypto/secure_hash.cc index 868300f0f78e11..2a5a1f02089e6f 100644 --- a/crypto/secure_hash_openssl.cc +++ b/crypto/secure_hash.cc @@ -16,17 +16,17 @@ namespace crypto { namespace { -class SecureHashSHA256OpenSSL : public SecureHash { +class SecureHashSHA256 : public SecureHash { public: - SecureHashSHA256OpenSSL() { + SecureHashSHA256() { SHA256_Init(&ctx_); } - SecureHashSHA256OpenSSL(const SecureHashSHA256OpenSSL& other) { + SecureHashSHA256(const SecureHashSHA256& other) { memcpy(&ctx_, &other.ctx_, sizeof(ctx_)); } - ~SecureHashSHA256OpenSSL() override { + ~SecureHashSHA256() override { OPENSSL_cleanse(&ctx_, sizeof(ctx_)); } @@ -41,7 +41,7 @@ class SecureHashSHA256OpenSSL : public SecureHash { } SecureHash* Clone() const override { - return new SecureHashSHA256OpenSSL(*this); + return new SecureHashSHA256(*this); } size_t GetHashLength() const override { return SHA256_DIGEST_LENGTH; } @@ -55,7 +55,7 @@ class SecureHashSHA256OpenSSL : public SecureHash { SecureHash* SecureHash::Create(Algorithm algorithm) { switch (algorithm) { case SHA256: - return new SecureHashSHA256OpenSSL(); + return new SecureHashSHA256(); default: NOTIMPLEMENTED(); return NULL; diff --git a/crypto/signature_creator_openssl.cc b/crypto/signature_creator.cc similarity index 100% rename from crypto/signature_creator_openssl.cc rename to crypto/signature_creator.cc diff --git a/crypto/signature_verifier_openssl.cc b/crypto/signature_verifier.cc similarity index 100% rename from crypto/signature_verifier_openssl.cc rename to crypto/signature_verifier.cc