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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/crypto/encryptor.h ('k') | base/crypto/encryptor_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/crypto/encryptor.h" 5 #include "base/crypto/encryptor.h"
6 6
7 #include <openssl/aes.h>
8 #include <openssl/evp.h>
9
10 #include "base/crypto/symmetric_key.h"
7 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/openssl_util.h"
13 #include "base/string_util.h"
8 14
9 namespace base { 15 namespace base {
10 16
17 namespace {
18
19 const EVP_CIPHER* GetCipherForKey(SymmetricKey* key) {
20 size_t key_len = key->key().length();
21 if (16 == key_len)
22 return EVP_aes_128_cbc();
23 if (32 == key_len)
24 return EVP_aes_256_cbc();
25 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.
26 }
27
28 // On destruction this class will cleanup |ctx|.
29 class ScopedCipherCTXCleanup {
30 public:
31 explicit ScopedCipherCTXCleanup(EVP_CIPHER_CTX* ctx) : ctx_(ctx) { }
32 ~ScopedCipherCTXCleanup() {
33 EVP_CIPHER_CTX_cleanup(ctx_);
34 }
35
36 private:
37 EVP_CIPHER_CTX* ctx_;
38 };
39
40 } // namespace
41
11 Encryptor::Encryptor() { 42 Encryptor::Encryptor() {
12 } 43 }
13 44
14 Encryptor::~Encryptor() { 45 Encryptor::~Encryptor() {
15 } 46 }
16 47
17 bool Encryptor::Init(SymmetricKey* key, Mode mode, const std::string& iv) { 48 bool Encryptor::Init(SymmetricKey* key, Mode mode, const std::string& iv) {
18 NOTIMPLEMENTED(); 49 DCHECK(key);
19 return false; 50 DCHECK_EQ(CBC, mode);
51
52 if (iv.size() != AES_BLOCK_SIZE)
53 return false;
54
55 if (GetCipherForKey(key) == NULL)
56 return false;
57
58 key_ = key;
59 mode_ = mode;
60 iv_ = iv;
61 return true;
20 } 62 }
21 63
22 bool Encryptor::Encrypt(const std::string& plaintext, std::string* ciphertext) { 64 bool Encryptor::Encrypt(const std::string& plaintext, std::string* ciphertext) {
23 NOTIMPLEMENTED(); 65 return Crypt(true, plaintext, ciphertext);
24 return false;
25 } 66 }
26 67
27 bool Encryptor::Decrypt(const std::string& ciphertext, std::string* plaintext) { 68 bool Encryptor::Decrypt(const std::string& ciphertext, std::string* plaintext) {
28 NOTIMPLEMENTED(); 69 return Crypt(false, ciphertext, plaintext);
29 return false; 70 }
71
72 bool Encryptor::Crypt(bool do_encrypt,
73 const std::string& input,
74 std::string* output) {
75 // Work on the result in a local variable, and then only transfer it to
76 // |output| on success to ensure no partial data is returned.
77 std::string result;
78 output->swap(result);
79
80 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.
81 return false;
82
83 ScopedERRStackClearer err_stack;
84 const EVP_CIPHER* cipher = GetCipherForKey(key_);
85 DCHECK(cipher); // Already handled in Init();
86
87 const std::string& key = key_->key();
88 DCHECK_EQ(EVP_CIPHER_iv_length(cipher), static_cast<int>(iv_.length()));
89 DCHECK_EQ(EVP_CIPHER_key_length(cipher), static_cast<int>(key.length()));
90
91 EVP_CIPHER_CTX ctx;
92 EVP_CIPHER_CTX_init(&ctx);
93 ScopedCipherCTXCleanup ctx_cleanup(&ctx);
94
95 if (!EVP_CipherInit_ex(&ctx, cipher, NULL,
96 reinterpret_cast<const uint8*>(key.data()),
97 reinterpret_cast<const uint8*>(iv_.data()),
98 do_encrypt))
99 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.
100
101 // 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
102 const size_t output_size = input.size() + (do_encrypt ? iv_.size() : 0);
103 uint8* out_ptr = reinterpret_cast<uint8*>(WriteInto(&result,
104 output_size + 1));
105 int out_len;
106 if (!EVP_CipherUpdate(&ctx, out_ptr, &out_len,
107 reinterpret_cast<const uint8*>(input.data()),
108 input.length()))
109 return false;
110
111 // Write out the final block plus padding (if any) to the end of the data
112 // just written.
113 int tail_len;
114 if (!EVP_CipherFinal_ex(&ctx, out_ptr + out_len, &tail_len))
115 return false;
116
117 out_len += tail_len;
118 DCHECK_LE(out_len, static_cast<int>(output_size));
119 result.resize(out_len);
120
121 output->swap(result);
122 return true;
30 } 123 }
31 124
32 } // namespace base 125 } // namespace base
OLDNEW
« 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