Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Unified Diff: base/crypto/encryptor_openssl.cc

Issue 4777001: Implements encryptor_openssl.cc (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: lint Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/crypto/encryptor.h ('k') | base/crypto/encryptor_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/crypto/encryptor_openssl.cc
diff --git a/base/crypto/encryptor_openssl.cc b/base/crypto/encryptor_openssl.cc
index 71a84be710dcf5dc31e08063bd5b8f2dbe21fa8d..917867777b9d2a4f720bd76d842891c26899909e 100644
--- a/base/crypto/encryptor_openssl.cc
+++ b/base/crypto/encryptor_openssl.cc
@@ -4,10 +4,41 @@
#include "base/crypto/encryptor.h"
+#include <openssl/aes.h>
+#include <openssl/evp.h>
+
+#include "base/crypto/symmetric_key.h"
#include "base/logging.h"
+#include "base/openssl_util.h"
+#include "base/string_util.h"
namespace base {
+namespace {
+
+const EVP_CIPHER* GetCipherForKey(SymmetricKey* key) {
+ size_t key_len = key->key().length();
+ if (16 == key_len)
+ return EVP_aes_128_cbc();
+ if (32 == key_len)
+ return EVP_aes_256_cbc();
+ return NULL;
Ryan Sleevi 2010/11/11 17:59:30 Nit: The other impls also support EVP_aes_192_cbc(
joth 2010/11/11 20:32:01 Done.
+}
+
+// On destruction this class will cleanup |ctx|.
+class ScopedCipherCTXCleanup {
+ public:
+ explicit ScopedCipherCTXCleanup(EVP_CIPHER_CTX* ctx) : ctx_(ctx) { }
+ ~ScopedCipherCTXCleanup() {
+ EVP_CIPHER_CTX_cleanup(ctx_);
+ }
+
+ private:
+ EVP_CIPHER_CTX* ctx_;
+};
+
+} // namespace
+
Encryptor::Encryptor() {
}
@@ -15,18 +46,80 @@ Encryptor::~Encryptor() {
}
bool Encryptor::Init(SymmetricKey* key, Mode mode, const std::string& iv) {
- NOTIMPLEMENTED();
- return false;
+ DCHECK(key);
+ DCHECK_EQ(CBC, mode);
+
+ if (iv.size() != AES_BLOCK_SIZE)
+ return false;
+
+ if (GetCipherForKey(key) == NULL)
+ return false;
+
+ key_ = key;
+ mode_ = mode;
+ iv_ = iv;
+ return true;
}
bool Encryptor::Encrypt(const std::string& plaintext, std::string* ciphertext) {
- NOTIMPLEMENTED();
- return false;
+ return Crypt(true, plaintext, ciphertext);
}
bool Encryptor::Decrypt(const std::string& ciphertext, std::string* plaintext) {
- NOTIMPLEMENTED();
- return false;
+ return Crypt(false, ciphertext, plaintext);
+}
+
+bool Encryptor::Crypt(bool do_encrypt,
+ const std::string& input,
+ std::string* output) {
+ // 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->swap(result);
+
+ if (input.size() == 0)
agl 2010/11/11 18:05:36 Why is this a failure? Everything is well defined
joth 2010/11/11 20:32:01 Good question. I just copied it from NSS.... :) M
agl 2010/11/11 20:39:45 Well a zero length input to decrypt *is* invalid.
+ return false;
+
+ ScopedERRStackClearer err_stack;
+ 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), static_cast<int>(iv_.length()));
+ DCHECK_EQ(EVP_CIPHER_key_length(cipher), static_cast<int>(key.length()));
+
+ EVP_CIPHER_CTX ctx;
+ EVP_CIPHER_CTX_init(&ctx);
+ ScopedCipherCTXCleanup ctx_cleanup(&ctx);
+
+ if (!EVP_CipherInit_ex(&ctx, cipher, NULL,
+ reinterpret_cast<const uint8*>(key.data()),
+ reinterpret_cast<const uint8*>(iv_.data()),
+ do_encrypt))
+ return false;
Ryan Sleevi 2010/11/11 17:59:30 Nit: Add an extra space for 96-98; alignment shoul
joth 2010/11/11 20:32:01 Done.
+
+ // When encrypting, add another block size of space to allow for any padding.
agl 2010/11/11 18:05:36 I guess that we don't actually know if each of the
joth 2010/11/11 20:32:01 AFAICS they all claim to do padding, don't know if
+ const size_t output_size = input.size() + (do_encrypt ? iv_.size() : 0);
+ uint8* out_ptr = reinterpret_cast<uint8*>(WriteInto(&result,
+ output_size + 1));
+ int out_len;
+ if (!EVP_CipherUpdate(&ctx, out_ptr, &out_len,
+ reinterpret_cast<const uint8*>(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, out_ptr + out_len, &tail_len))
+ return false;
+
+ out_len += tail_len;
+ DCHECK_LE(out_len, static_cast<int>(output_size));
+ result.resize(out_len);
+
+ output->swap(result);
+ return true;
}
} // namespace base
« no previous file with comments | « base/crypto/encryptor.h ('k') | base/crypto/encryptor_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698