summaryrefslogtreecommitdiffstats
path: root/crypto/encryptor_openssl.cc
diff options
context:
space:
mode:
authorxhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-13 19:48:01 +0000
committerxhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-13 19:48:01 +0000
commita3f742697f50cae3ace0a84a3ace1dde9beaef65 (patch)
tree1160547489bf6fb94af068a029d7cf70ae34769f /crypto/encryptor_openssl.cc
parentdf29744db2dfe21c90308089ff70197a5dd710f0 (diff)
downloadchromium_src-a3f742697f50cae3ace0a84a3ace1dde9beaef65.zip
chromium_src-a3f742697f50cae3ace0a84a3ace1dde9beaef65.tar.gz
chromium_src-a3f742697f50cae3ace0a84a3ace1dde9beaef65.tar.bz2
Support CTR-AES in encryptor_openssl.
BUG=163552 TEST=Added unittest to cover CTR-AES encryption/decryption. Also tested AesDecryptorTest in media_unittests. Review URL: https://chromiumcodereview.appspot.com/16654005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@206141 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'crypto/encryptor_openssl.cc')
-rw-r--r--crypto/encryptor_openssl.cc50
1 files changed, 46 insertions, 4 deletions
diff --git a/crypto/encryptor_openssl.cc b/crypto/encryptor_openssl.cc
index b643c72..0bf96b7 100644
--- a/crypto/encryptor_openssl.cc
+++ b/crypto/encryptor_openssl.cc
@@ -56,10 +56,10 @@ bool Encryptor::Init(SymmetricKey* key,
Mode mode,
const base::StringPiece& iv) {
DCHECK(key);
- DCHECK_EQ(CBC, mode);
+ DCHECK(mode == CBC || mode == CTR);
EnsureOpenSSLInit();
- if (iv.size() != AES_BLOCK_SIZE)
+ if (mode == CBC && iv.size() != AES_BLOCK_SIZE)
return false;
if (GetCipherForKey(key) == NULL)
@@ -74,13 +74,17 @@ bool Encryptor::Init(SymmetricKey* key,
bool Encryptor::Encrypt(const base::StringPiece& plaintext,
std::string* ciphertext) {
CHECK(!plaintext.empty() || (mode_ == CBC));
- return Crypt(true, plaintext, ciphertext);
+ 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 Crypt(false, ciphertext, plaintext);
+ return (mode_ == CTR) ?
+ CryptCTR(false, ciphertext, plaintext) :
+ Crypt(false, ciphertext, plaintext);
}
bool Encryptor::Crypt(bool do_encrypt,
@@ -132,4 +136,42 @@ bool Encryptor::Crypt(bool do_encrypt,
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<const uint8*>(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* out_ptr = reinterpret_cast<uint8*>(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<const uint8*>(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<const char*>(ivec),
+ AES_BLOCK_SIZE));
+
+ output->swap(result);
+ return true;
+}
+
} // namespace crypto