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

Side by Side Diff: crypto/encryptor_nss.cc

Issue 8511050: Unify the error checking of crypto::Encryptor and add WARN_UNUSED_RESULT to prevent misuse. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix typo Created 8 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « crypto/encryptor_mac.cc ('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) 2011 The Chromium Authors. All rights reserved. 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 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 <cryptohi.h> 7 #include <cryptohi.h>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/string_util.h"
11 #include "crypto/nss_util.h" 12 #include "crypto/nss_util.h"
12 #include "crypto/symmetric_key.h" 13 #include "crypto/symmetric_key.h"
13 14
14 namespace crypto { 15 namespace crypto {
15 16
16 namespace { 17 namespace {
17 18
18 inline CK_MECHANISM_TYPE GetMechanism(Encryptor::Mode mode) { 19 inline CK_MECHANISM_TYPE GetMechanism(Encryptor::Mode mode) {
19 switch (mode) { 20 switch (mode) {
20 case Encryptor::CBC: 21 case Encryptor::CBC:
(...skipping 16 matching lines...) Expand all
37 mode_(CBC) { 38 mode_(CBC) {
38 EnsureNSSInit(); 39 EnsureNSSInit();
39 } 40 }
40 41
41 Encryptor::~Encryptor() { 42 Encryptor::~Encryptor() {
42 } 43 }
43 44
44 bool Encryptor::Init(SymmetricKey* key, 45 bool Encryptor::Init(SymmetricKey* key,
45 Mode mode, 46 Mode mode,
46 const base::StringPiece& iv) { 47 const base::StringPiece& iv) {
47 DCHECK(key); 48 DCHECK(CBC == mode || CTR == mode);
48 DCHECK(CBC == mode || CTR == mode) << "Unsupported mode of operation"; 49 if (!key)
50 return false;
49 51
50 key_ = key; 52 key_ = key;
51 mode_ = mode; 53 mode_ = mode;
52 54
53 if (mode == CBC && iv.size() != AES_BLOCK_SIZE) 55 if (mode == CBC && iv.size() != AES_BLOCK_SIZE)
54 return false; 56 return false;
55 57
56 slot_.reset(PK11_GetBestSlot(GetMechanism(mode), NULL)); 58 slot_.reset(PK11_GetBestSlot(GetMechanism(mode), NULL));
57 if (!slot_.get()) 59 if (!slot_.get())
58 return false; 60 return false;
(...skipping 11 matching lines...) Expand all
70 case CTR: 72 case CTR:
71 param_.reset(PK11_ParamFromIV(GetMechanism(mode), NULL)); 73 param_.reset(PK11_ParamFromIV(GetMechanism(mode), NULL));
72 break; 74 break;
73 } 75 }
74 76
75 return param_ != NULL; 77 return param_ != NULL;
76 } 78 }
77 79
78 bool Encryptor::Encrypt(const base::StringPiece& plaintext, 80 bool Encryptor::Encrypt(const base::StringPiece& plaintext,
79 std::string* ciphertext) { 81 std::string* ciphertext) {
80 CHECK(!plaintext.empty() || (mode_ == CBC)); 82 if (plaintext.empty() && mode_ != CBC)
83 return false;
84
81 ScopedPK11Context context(PK11_CreateContextBySymKey(GetMechanism(mode_), 85 ScopedPK11Context context(PK11_CreateContextBySymKey(GetMechanism(mode_),
82 CKA_ENCRYPT, 86 CKA_ENCRYPT,
83 key_->key(), 87 key_->key(),
84 param_.get())); 88 param_.get()));
85 if (!context.get()) 89 if (!context.get())
86 return false; 90 return false;
87 91
88 return (mode_ == CTR) ? 92 return (mode_ == CTR) ?
89 CryptCTR(context.get(), plaintext, ciphertext) : 93 CryptCTR(context.get(), plaintext, ciphertext) :
90 Crypt(context.get(), plaintext, ciphertext); 94 Crypt(context.get(), plaintext, ciphertext);
91 } 95 }
92 96
93 bool Encryptor::Decrypt(const base::StringPiece& ciphertext, 97 bool Encryptor::Decrypt(const base::StringPiece& ciphertext,
94 std::string* plaintext) { 98 std::string* plaintext) {
95 CHECK(!ciphertext.empty()); 99 if (ciphertext.empty())
100 return false;
101
96 ScopedPK11Context context(PK11_CreateContextBySymKey( 102 ScopedPK11Context context(PK11_CreateContextBySymKey(
97 GetMechanism(mode_), (mode_ == CTR ? CKA_ENCRYPT : CKA_DECRYPT), 103 GetMechanism(mode_), (mode_ == CTR ? CKA_ENCRYPT : CKA_DECRYPT),
98 key_->key(), param_.get())); 104 key_->key(), param_.get()));
99 if (!context.get()) 105 if (!context.get())
100 return false; 106 return false;
101 107
102 return (mode_ == CTR) ? 108 return (mode_ == CTR) ?
103 CryptCTR(context.get(), ciphertext, plaintext) : 109 CryptCTR(context.get(), ciphertext, plaintext) :
104 Crypt(context.get(), ciphertext, plaintext); 110 Crypt(context.get(), ciphertext, plaintext);
105 } 111 }
106 112
107 bool Encryptor::Crypt(PK11Context* context, 113 bool Encryptor::Crypt(PK11Context* context,
108 const base::StringPiece& input, 114 const base::StringPiece& input,
109 std::string* output) { 115 std::string* output) {
110 size_t output_len = input.size() + AES_BLOCK_SIZE; 116 size_t output_len = input.size() + AES_BLOCK_SIZE;
111 CHECK_GT(output_len, input.size()); 117 if (output_len == 0 || output_len + 1 < input.size())
112 118 return false;
113 output->resize(output_len);
114 uint8* output_data =
115 reinterpret_cast<uint8*>(const_cast<char*>(output->data()));
116 119
117 int input_len = input.size(); 120 int input_len = input.size();
118 uint8* input_data = 121 uint8* input_data =
119 reinterpret_cast<uint8*>(const_cast<char*>(input.data())); 122 reinterpret_cast<uint8*>(const_cast<char*>(input.data()));
123 uint8* output_data =
124 reinterpret_cast<uint8*>(WriteInto(output, output_len + 1));
120 125
121 int op_len; 126 int op_len;
122 SECStatus rv = PK11_CipherOp(context, 127 SECStatus rv = PK11_CipherOp(context, output_data, &op_len, output_len,
123 output_data, 128 input_data, input_len);
124 &op_len, 129 if (SECSuccess != rv)
125 output_len,
126 input_data,
127 input_len);
128
129 if (SECSuccess != rv) {
130 output->clear();
131 return false; 130 return false;
132 }
133 131
134 unsigned int digest_len; 132 unsigned int digest_len;
135 rv = PK11_DigestFinal(context, 133 rv = PK11_DigestFinal(context, output_data + op_len, &digest_len,
136 output_data + op_len,
137 &digest_len,
138 output_len - op_len); 134 output_len - op_len);
139 if (SECSuccess != rv) { 135 if (SECSuccess != rv)
140 output->clear();
141 return false; 136 return false;
142 }
143 137
144 output->resize(op_len + digest_len); 138 output->resize(op_len + digest_len);
145 return true; 139 return true;
146 } 140 }
147 141
148 bool Encryptor::CryptCTR(PK11Context* context, 142 bool Encryptor::CryptCTR(PK11Context* context,
149 const base::StringPiece& input, 143 const base::StringPiece& input,
150 std::string* output) { 144 std::string* output) {
151 if (!counter_.get()) { 145 if (!counter_.get()) {
152 LOG(ERROR) << "Counter value not set in CTR mode."; 146 LOG(ERROR) << "Counter value not set in CTR mode.";
153 return false; 147 return false;
154 } 148 }
155 149
156 size_t output_len = ((input.size() + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE) * 150 size_t output_len = ((input.size() + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE) *
157 AES_BLOCK_SIZE; 151 AES_BLOCK_SIZE;
158 CHECK_GE(output_len, input.size()); 152 if (output_len == 0 || output_len + 1 < input.size())
159 output->resize(output_len); 153 return false;
154
160 uint8* output_data = 155 uint8* output_data =
161 reinterpret_cast<uint8*>(const_cast<char*>(output->data())); 156 reinterpret_cast<uint8*>(WriteInto(output, output_len + 1));
162 157
163 size_t mask_len; 158 size_t mask_len;
164 bool ret = GenerateCounterMask(input.size(), output_data, &mask_len); 159 bool ret = GenerateCounterMask(input.size(), output_data, &mask_len);
165 if (!ret) 160 if (!ret)
166 return false; 161 return false;
167 162
168 CHECK_EQ(mask_len, output_len); 163 CHECK_EQ(mask_len, output_len);
169 int op_len; 164 int op_len;
170 SECStatus rv = PK11_CipherOp(context, 165 SECStatus rv = PK11_CipherOp(context, output_data, &op_len, output_len,
171 output_data, 166 output_data, mask_len);
172 &op_len,
173 output_len,
174 output_data,
175 mask_len);
176 if (SECSuccess != rv) 167 if (SECSuccess != rv)
177 return false; 168 return false;
178 CHECK_EQ(static_cast<int>(mask_len), op_len); 169 CHECK_EQ(static_cast<int>(mask_len), op_len);
179 170
180 unsigned int digest_len; 171 unsigned int digest_len;
181 rv = PK11_DigestFinal(context, 172 rv = PK11_DigestFinal(context, NULL, &digest_len, 0);
182 NULL,
183 &digest_len,
184 0);
185 if (SECSuccess != rv) 173 if (SECSuccess != rv)
186 return false; 174 return false;
187 CHECK(!digest_len); 175 CHECK(!digest_len);
188 176
189 // Use |output_data| to mask |input|. 177 // Use |output_data| to mask |input|.
190 MaskMessage( 178 MaskMessage(reinterpret_cast<uint8*>(const_cast<char*>(input.data())),
191 reinterpret_cast<uint8*>(const_cast<char*>(input.data())), 179 input.size(), output_data, output_data);
192 input.length(), output_data, output_data); 180 output->resize(input.size());
193 output->resize(input.length());
194 return true; 181 return true;
195 } 182 }
196 183
197 } // namespace crypto 184 } // namespace crypto
OLDNEW
« no previous file with comments | « crypto/encryptor_mac.cc ('k') | crypto/encryptor_openssl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698