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

Side by Side Diff: crypto/encryptor.cc

Issue 1909513003: Rename crypto/ *_openssl files (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months 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
« no previous file with comments | « crypto/encryptor.h ('k') | crypto/encryptor_openssl.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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "crypto/encryptor.h" 5 #include "crypto/encryptor.h"
6 6
7 #include <openssl/aes.h>
8 #include <openssl/evp.h>
7 #include <stddef.h> 9 #include <stddef.h>
8 #include <stdint.h> 10 #include <stdint.h>
9 11
10 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/strings/string_util.h"
11 #include "base/sys_byteorder.h" 14 #include "base/sys_byteorder.h"
15 #include "crypto/openssl_util.h"
16 #include "crypto/symmetric_key.h"
12 17
13 namespace crypto { 18 namespace crypto {
14 19
20 namespace {
21
22 const EVP_CIPHER* GetCipherForKey(SymmetricKey* key) {
23 switch (key->key().length()) {
24 case 16: return EVP_aes_128_cbc();
25 case 32: return EVP_aes_256_cbc();
26 default: return NULL;
27 }
28 }
29
30 // On destruction this class will cleanup the ctx, and also clear the OpenSSL
31 // ERR stack as a convenience.
32 class ScopedCipherCTX {
33 public:
34 explicit ScopedCipherCTX() {
35 EVP_CIPHER_CTX_init(&ctx_);
36 }
37 ~ScopedCipherCTX() {
38 EVP_CIPHER_CTX_cleanup(&ctx_);
39 ClearOpenSSLERRStack(FROM_HERE);
40 }
41 EVP_CIPHER_CTX* get() { return &ctx_; }
42
43 private:
44 EVP_CIPHER_CTX ctx_;
45 };
46
47 } // namespace
48
15 ///////////////////////////////////////////////////////////////////////////// 49 /////////////////////////////////////////////////////////////////////////////
16 // Encyptor::Counter Implementation. 50 // Encyptor::Counter Implementation.
17 Encryptor::Counter::Counter(const base::StringPiece& counter) { 51 Encryptor::Counter::Counter(const base::StringPiece& counter) {
18 CHECK(sizeof(counter_) == counter.length()); 52 CHECK(sizeof(counter_) == counter.length());
19 53
20 memcpy(&counter_, counter.data(), sizeof(counter_)); 54 memcpy(&counter_, counter.data(), sizeof(counter_));
21 } 55 }
22 56
23 Encryptor::Counter::~Counter() { 57 Encryptor::Counter::~Counter() {
24 } 58 }
(...skipping 16 matching lines...) Expand all
41 void Encryptor::Counter::Write(void* buf) { 75 void Encryptor::Counter::Write(void* buf) {
42 uint8_t* buf_ptr = reinterpret_cast<uint8_t*>(buf); 76 uint8_t* buf_ptr = reinterpret_cast<uint8_t*>(buf);
43 memcpy(buf_ptr, &counter_, sizeof(counter_)); 77 memcpy(buf_ptr, &counter_, sizeof(counter_));
44 } 78 }
45 79
46 size_t Encryptor::Counter::GetLengthInBytes() const { 80 size_t Encryptor::Counter::GetLengthInBytes() const {
47 return sizeof(counter_); 81 return sizeof(counter_);
48 } 82 }
49 83
50 ///////////////////////////////////////////////////////////////////////////// 84 /////////////////////////////////////////////////////////////////////////////
51 // Partial Encryptor Implementation. 85 // Encryptor Implementation.
86
87 Encryptor::Encryptor()
88 : key_(NULL),
89 mode_(CBC) {
90 }
91
92 Encryptor::~Encryptor() {
93 }
94
95 bool Encryptor::Init(SymmetricKey* key,
96 Mode mode,
97 const base::StringPiece& iv) {
98 DCHECK(key);
99 DCHECK(mode == CBC || mode == CTR);
100
101 EnsureOpenSSLInit();
102 if (mode == CBC && iv.size() != AES_BLOCK_SIZE)
103 return false;
104
105 if (GetCipherForKey(key) == NULL)
106 return false;
107
108 key_ = key;
109 mode_ = mode;
110 iv.CopyToString(&iv_);
111 return true;
112 }
113
114 bool Encryptor::Encrypt(const base::StringPiece& plaintext,
115 std::string* ciphertext) {
116 CHECK(!plaintext.empty() || (mode_ == CBC));
117 return (mode_ == CTR) ?
118 CryptCTR(true, plaintext, ciphertext) :
119 Crypt(true, plaintext, ciphertext);
120 }
121
122 bool Encryptor::Decrypt(const base::StringPiece& ciphertext,
123 std::string* plaintext) {
124 CHECK(!ciphertext.empty());
125 return (mode_ == CTR) ?
126 CryptCTR(false, ciphertext, plaintext) :
127 Crypt(false, ciphertext, plaintext);
128 }
52 129
53 bool Encryptor::SetCounter(const base::StringPiece& counter) { 130 bool Encryptor::SetCounter(const base::StringPiece& counter) {
54 if (mode_ != CTR) 131 if (mode_ != CTR)
55 return false; 132 return false;
56 if (counter.length() != 16u) 133 if (counter.length() != 16u)
57 return false; 134 return false;
58 135
59 counter_.reset(new Counter(counter)); 136 counter_.reset(new Counter(counter));
60 return true; 137 return true;
61 } 138 }
(...skipping 28 matching lines...) Expand all
90 void* ciphertext) const { 167 void* ciphertext) const {
91 DCHECK_EQ(CTR, mode_); 168 DCHECK_EQ(CTR, mode_);
92 const uint8_t* plaintext_ptr = reinterpret_cast<const uint8_t*>(plaintext); 169 const uint8_t* plaintext_ptr = reinterpret_cast<const uint8_t*>(plaintext);
93 const uint8_t* mask_ptr = reinterpret_cast<const uint8_t*>(mask); 170 const uint8_t* mask_ptr = reinterpret_cast<const uint8_t*>(mask);
94 uint8_t* ciphertext_ptr = reinterpret_cast<uint8_t*>(ciphertext); 171 uint8_t* ciphertext_ptr = reinterpret_cast<uint8_t*>(ciphertext);
95 172
96 for (size_t i = 0; i < plaintext_len; ++i) 173 for (size_t i = 0; i < plaintext_len; ++i)
97 ciphertext_ptr[i] = plaintext_ptr[i] ^ mask_ptr[i]; 174 ciphertext_ptr[i] = plaintext_ptr[i] ^ mask_ptr[i];
98 } 175 }
99 176
177 bool Encryptor::Crypt(bool do_encrypt,
178 const base::StringPiece& input,
179 std::string* output) {
180 DCHECK(key_); // Must call Init() before En/De-crypt.
181 // Work on the result in a local variable, and then only transfer it to
182 // |output| on success to ensure no partial data is returned.
183 std::string result;
184 output->clear();
185
186 const EVP_CIPHER* cipher = GetCipherForKey(key_);
187 DCHECK(cipher); // Already handled in Init();
188
189 const std::string& key = key_->key();
190 DCHECK_EQ(EVP_CIPHER_iv_length(cipher), iv_.length());
191 DCHECK_EQ(EVP_CIPHER_key_length(cipher), key.length());
192
193 ScopedCipherCTX ctx;
194 if (!EVP_CipherInit_ex(
195 ctx.get(), cipher, NULL, reinterpret_cast<const uint8_t*>(key.data()),
196 reinterpret_cast<const uint8_t*>(iv_.data()), do_encrypt))
197 return false;
198
199 // When encrypting, add another block size of space to allow for any padding.
200 const size_t output_size = input.size() + (do_encrypt ? iv_.size() : 0);
201 CHECK_GT(output_size, 0u);
202 CHECK_GT(output_size + 1, input.size());
203 uint8_t* out_ptr =
204 reinterpret_cast<uint8_t*>(base::WriteInto(&result, output_size + 1));
205 int out_len;
206 if (!EVP_CipherUpdate(ctx.get(), out_ptr, &out_len,
207 reinterpret_cast<const uint8_t*>(input.data()),
208 input.length()))
209 return false;
210
211 // Write out the final block plus padding (if any) to the end of the data
212 // just written.
213 int tail_len;
214 if (!EVP_CipherFinal_ex(ctx.get(), out_ptr + out_len, &tail_len))
215 return false;
216
217 out_len += tail_len;
218 DCHECK_LE(out_len, static_cast<int>(output_size));
219 result.resize(out_len);
220
221 output->swap(result);
222 return true;
223 }
224
225 bool Encryptor::CryptCTR(bool do_encrypt,
226 const base::StringPiece& input,
227 std::string* output) {
228 if (!counter_.get()) {
229 LOG(ERROR) << "Counter value not set in CTR mode.";
230 return false;
231 }
232
233 AES_KEY aes_key;
234 if (AES_set_encrypt_key(reinterpret_cast<const uint8_t*>(key_->key().data()),
235 key_->key().size() * 8, &aes_key) != 0) {
236 return false;
237 }
238
239 const size_t out_size = input.size();
240 CHECK_GT(out_size, 0u);
241 CHECK_GT(out_size + 1, input.size());
242
243 std::string result;
244 uint8_t* out_ptr =
245 reinterpret_cast<uint8_t*>(base::WriteInto(&result, out_size + 1));
246
247 uint8_t ivec[AES_BLOCK_SIZE] = { 0 };
248 uint8_t ecount_buf[AES_BLOCK_SIZE] = { 0 };
249 unsigned int block_offset = 0;
250
251 counter_->Write(ivec);
252
253 AES_ctr128_encrypt(reinterpret_cast<const uint8_t*>(input.data()), out_ptr,
254 input.size(), &aes_key, ivec, ecount_buf, &block_offset);
255
256 // AES_ctr128_encrypt() updates |ivec|. Update the |counter_| here.
257 SetCounter(base::StringPiece(reinterpret_cast<const char*>(ivec),
258 AES_BLOCK_SIZE));
259
260 output->swap(result);
261 return true;
262 }
263
100 } // namespace crypto 264 } // namespace crypto
OLDNEW
« no previous file with comments | « crypto/encryptor.h ('k') | crypto/encryptor_openssl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698