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

Side by Side Diff: crypto/encryptor_nss.cc

Issue 1882433002: Removing NSS files and USE_OPENSSL flag (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. 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/hmac_nss.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "crypto/encryptor.h"
6
7 #include <cryptohi.h>
8 #include <stddef.h>
9 #include <stdint.h>
10 #include <vector>
11
12 #include "base/logging.h"
13 #include "crypto/nss_util.h"
14 #include "crypto/symmetric_key.h"
15
16 namespace crypto {
17
18 namespace {
19
20 inline CK_MECHANISM_TYPE GetMechanism(Encryptor::Mode mode) {
21 switch (mode) {
22 case Encryptor::CBC:
23 return CKM_AES_CBC_PAD;
24 case Encryptor::CTR:
25 // AES-CTR encryption uses ECB encryptor as a building block since
26 // NSS doesn't support CTR encryption mode.
27 return CKM_AES_ECB;
28 default:
29 NOTREACHED() << "Unsupported mode of operation";
30 break;
31 }
32 return static_cast<CK_MECHANISM_TYPE>(-1);
33 }
34
35 } // namespace
36
37 Encryptor::Encryptor()
38 : key_(NULL),
39 mode_(CBC) {
40 EnsureNSSInit();
41 }
42
43 Encryptor::~Encryptor() {
44 }
45
46 bool Encryptor::Init(SymmetricKey* key,
47 Mode mode,
48 const base::StringPiece& iv) {
49 DCHECK(key);
50 DCHECK(CBC == mode || CTR == mode) << "Unsupported mode of operation";
51
52 key_ = key;
53 mode_ = mode;
54
55 if (mode == CBC && iv.size() != AES_BLOCK_SIZE)
56 return false;
57
58 switch (mode) {
59 case CBC:
60 SECItem iv_item;
61 iv_item.type = siBuffer;
62 iv_item.data = reinterpret_cast<unsigned char*>(
63 const_cast<char *>(iv.data()));
64 iv_item.len = iv.size();
65
66 param_.reset(PK11_ParamFromIV(GetMechanism(mode), &iv_item));
67 break;
68 case CTR:
69 param_.reset(PK11_ParamFromIV(GetMechanism(mode), NULL));
70 break;
71 }
72
73 return param_ != NULL;
74 }
75
76 bool Encryptor::Encrypt(const base::StringPiece& plaintext,
77 std::string* ciphertext) {
78 CHECK(!plaintext.empty() || (mode_ == CBC));
79 ScopedPK11Context context(PK11_CreateContextBySymKey(GetMechanism(mode_),
80 CKA_ENCRYPT,
81 key_->key(),
82 param_.get()));
83 if (!context.get())
84 return false;
85
86 return (mode_ == CTR) ?
87 CryptCTR(context.get(), plaintext, ciphertext) :
88 Crypt(context.get(), plaintext, ciphertext);
89 }
90
91 bool Encryptor::Decrypt(const base::StringPiece& ciphertext,
92 std::string* plaintext) {
93 CHECK(!ciphertext.empty());
94 ScopedPK11Context context(PK11_CreateContextBySymKey(
95 GetMechanism(mode_), (mode_ == CTR ? CKA_ENCRYPT : CKA_DECRYPT),
96 key_->key(), param_.get()));
97 if (!context.get())
98 return false;
99
100 if (mode_ == CTR)
101 return CryptCTR(context.get(), ciphertext, plaintext);
102
103 if (ciphertext.size() % AES_BLOCK_SIZE != 0) {
104 // Decryption will fail if the input is not a multiple of the block size.
105 // PK11_CipherOp has a bug where it will do an invalid memory access before
106 // the start of the input, so avoid calling it. (NSS bug 922780).
107 plaintext->clear();
108 return false;
109 }
110
111 return Crypt(context.get(), ciphertext, plaintext);
112 }
113
114 bool Encryptor::Crypt(PK11Context* context,
115 const base::StringPiece& input,
116 std::string* output) {
117 size_t output_len = input.size() + AES_BLOCK_SIZE;
118 CHECK_GT(output_len, input.size());
119
120 output->resize(output_len);
121 uint8_t* output_data =
122 reinterpret_cast<uint8_t*>(const_cast<char*>(output->data()));
123
124 int input_len = input.size();
125 uint8_t* input_data =
126 reinterpret_cast<uint8_t*>(const_cast<char*>(input.data()));
127
128 int op_len;
129 SECStatus rv = PK11_CipherOp(context,
130 output_data,
131 &op_len,
132 output_len,
133 input_data,
134 input_len);
135
136 if (SECSuccess != rv) {
137 output->clear();
138 return false;
139 }
140
141 unsigned int digest_len;
142 rv = PK11_DigestFinal(context,
143 output_data + op_len,
144 &digest_len,
145 output_len - op_len);
146 if (SECSuccess != rv) {
147 output->clear();
148 return false;
149 }
150
151 output->resize(op_len + digest_len);
152 return true;
153 }
154
155 bool Encryptor::CryptCTR(PK11Context* context,
156 const base::StringPiece& input,
157 std::string* output) {
158 if (!counter_.get()) {
159 LOG(ERROR) << "Counter value not set in CTR mode.";
160 return false;
161 }
162
163 size_t output_len = ((input.size() + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE) *
164 AES_BLOCK_SIZE;
165 CHECK_GE(output_len, input.size());
166 output->resize(output_len);
167 uint8_t* output_data =
168 reinterpret_cast<uint8_t*>(const_cast<char*>(output->data()));
169
170 size_t mask_len;
171 bool ret = GenerateCounterMask(input.size(), output_data, &mask_len);
172 if (!ret)
173 return false;
174
175 CHECK_EQ(mask_len, output_len);
176 int op_len;
177 SECStatus rv = PK11_CipherOp(context,
178 output_data,
179 &op_len,
180 output_len,
181 output_data,
182 mask_len);
183 if (SECSuccess != rv)
184 return false;
185 CHECK_EQ(static_cast<int>(mask_len), op_len);
186
187 unsigned int digest_len;
188 rv = PK11_DigestFinal(context,
189 NULL,
190 &digest_len,
191 0);
192 if (SECSuccess != rv)
193 return false;
194 CHECK(!digest_len);
195
196 // Use |output_data| to mask |input|.
197 MaskMessage(reinterpret_cast<uint8_t*>(const_cast<char*>(input.data())),
198 input.length(), output_data, output_data);
199 output->resize(input.length());
200 return true;
201 }
202
203 } // namespace crypto
OLDNEW
« no previous file with comments | « crypto/encryptor.h ('k') | crypto/hmac_nss.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698