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

Side by Side Diff: crypto/openpgp_symmetric_encryption_nss.cc

Issue 7273080: crypto: convert OpenPGP code to NSS (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 5 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
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/openpgp_symmetric_encryption.h" 5 #include "crypto/openpgp_symmetric_encryption.h"
6 6
7 #include <vector> 7 #include <vector>
wtc 2011/07/01 18:33:32 <vector> is a C++ system header, so it should be l
agl 2011/07/01 20:04:59 Done.
8 #include <stdlib.h> 8 #include <stdlib.h>
9 9
10 #include <openssl/evp.h> 10 #include <sechash.h>
11 #include <openssl/aes.h> 11 #include <cryptohi.h>
12 #include <openssl/sha.h>
13 12
13 #include "base/logging.h"
14 #include "base/rand_util.h" 14 #include "base/rand_util.h"
15 #include "base/logging.h" 15 #include "crypto/scoped_nss_types.h"
16 16
17 namespace crypto { 17 namespace crypto {
18 18
19 namespace { 19 namespace {
20 20
21 // Reader wraps a StringPiece and provides methods to read several datatypes 21 // Reader wraps a StringPiece and provides methods to read several datatypes
22 // while advancing the StringPiece. 22 // while advancing the StringPiece.
23 class Reader { 23 class Reader {
24 public: 24 public:
25 Reader(base::StringPiece input) 25 Reader(base::StringPiece input)
(...skipping 14 matching lines...) Expand all
40 *out = static_cast<uint32>(data_[0]) << 24 | 40 *out = static_cast<uint32>(data_[0]) << 24 |
41 static_cast<uint32>(data_[1]) << 16 | 41 static_cast<uint32>(data_[1]) << 16 |
42 static_cast<uint32>(data_[2]) << 8 | 42 static_cast<uint32>(data_[2]) << 8 |
43 static_cast<uint32>(data_[3]); 43 static_cast<uint32>(data_[3]);
44 data_.remove_prefix(4); 44 data_.remove_prefix(4);
45 return true; 45 return true;
46 } 46 }
47 47
48 // Prefix sets |*out| to the first |n| bytes of the StringPiece and advances 48 // Prefix sets |*out| to the first |n| bytes of the StringPiece and advances
49 // the StringPiece by |n|. 49 // the StringPiece by |n|.
50 bool Prefix(uint32 n, base::StringPiece *out) { 50 bool Prefix(size_t n, base::StringPiece *out) {
51 if (data_.size() < n) 51 if (data_.size() < n)
52 return false; 52 return false;
53 *out = base::StringPiece(data_.data(), n); 53 *out = base::StringPiece(data_.data(), n);
54 data_.remove_prefix(n); 54 data_.remove_prefix(n);
55 return true; 55 return true;
56 } 56 }
57 57
58 // Remainder returns the remainer of the StringPiece and advances it to the 58 // Remainder returns the remainer of the StringPiece and advances it to the
59 // end. 59 // end.
60 base::StringPiece Remainder() { 60 base::StringPiece Remainder() {
61 base::StringPiece ret = data_; 61 base::StringPiece ret = data_;
62 data_ = base::StringPiece(); 62 data_ = base::StringPiece();
63 return ret; 63 return ret;
64 } 64 }
65 65
66 typedef base::StringPiece Position; 66 typedef base::StringPiece Position;
67 67
68 Position tell() const { 68 Position tell() const {
69 return data_; 69 return data_;
70 } 70 }
71 71
72 void Seek(Position p) { 72 void Seek(Position p) {
73 data_ = p; 73 data_ = p;
74 } 74 }
75 75
76 bool Skip(uint32 n) { 76 bool Skip(size_t n) {
77 if (data_.size() < n) 77 if (data_.size() < n)
78 return false; 78 return false;
79 data_.remove_prefix(n); 79 data_.remove_prefix(n);
80 return true; 80 return true;
81 } 81 }
82 82
83 bool empty() const { 83 bool empty() const {
84 return data_.empty(); 84 return data_.empty();
85 } 85 }
86 86
87 size_t size() const { 87 size_t size() const {
88 return data_.size(); 88 return data_.size();
89 } 89 }
90 90
91 private: 91 private:
92 base::StringPiece data_; 92 base::StringPiece data_;
93 }; 93 };
94 94
95 // SaltedIteratedS2K implements the salted and iterated string-to-key 95 // SaltedIteratedS2K implements the salted and iterated string-to-key
96 // convertion. See RFC 4880, section 3.7.1.3. 96 // convertion. See RFC 4880, section 3.7.1.3.
97 void SaltedIteratedS2K(uint32 cipher_key_length, 97 void SaltedIteratedS2K(unsigned cipher_key_length,
98 const EVP_MD *hash_function, 98 HASH_HashType hash_function,
99 base::StringPiece passphrase, 99 base::StringPiece passphrase,
100 base::StringPiece salt, 100 base::StringPiece salt,
101 uint32 count, 101 unsigned count,
102 uint8 *out_key) { 102 uint8 *out_key) {
103 const std::string combined = salt.as_string() + passphrase.as_string(); 103 const std::string combined = salt.as_string() + passphrase.as_string();
104 const size_t combined_len = combined.size(); 104 const size_t combined_len = combined.size();
105 105
106 uint32 done = 0; 106 unsigned done = 0;
107 uint8 zero[1] = {0}; 107 uint8 zero[1] = {0};
108 108
109 EVP_MD_CTX ctx; 109 const struct SECHashObjectStr* hash = HASH_GetHashObject(hash_function);
wtc 2011/07/01 18:33:32 struct SECHashObjectStr => SECHashObject Please s
agl 2011/07/01 20:04:59 Done.
110 EVP_MD_CTX_init(&context); 110 void* hash_context = hash->create();
111 111
112 for (uint32 i = 0; done < cipher_key_length; i++) { 112 for (unsigned i = 0; done < cipher_key_length; i++) {
113 CHECK_EQ(EVP_DigestInit_ex(&ctx, hash_function, NULL), 1); 113 hash->begin(hash_context);
114 114
115 for (uint32 j = 0; j < i; j++) 115 for (unsigned j = 0; j < i; j++)
116 EVP_DigestUpdate(&ctx, zero, sizeof(zero)); 116 hash->update(hash_context, zero, sizeof(zero));
117 117
118 uint32 written = 0; 118 unsigned written = 0;
119 while (written < count) { 119 while (written < count) {
120 if (written + combined_len > count) { 120 if (written + combined_len > count) {
121 uint32 todo = count - written; 121 unsigned todo = count - written;
122 EVP_DigestUpdate(&ctx, combined.data(), todo); 122 hash->update(hash_context,
123 reinterpret_cast<const uint8*>(combined.data()),
124 todo);
123 written = count; 125 written = count;
124 } else { 126 } else {
125 EVP_DigestUpdate(&ctx, combined.data(), combined_len); 127 hash->update(hash_context,
128 reinterpret_cast<const uint8*>(combined.data()),
129 combined_len);
126 written += combined_len; 130 written += combined_len;
127 } 131 }
128 } 132 }
129 133
130 uint32 num_hash_bytes; 134 unsigned num_hash_bytes;
131 uint8 hash[EVP_MAX_MD_SIZE]; 135 uint8 digest[HASH_LENGTH_MAX];
132 CHECK_EQ(EVP_DigestFinal_ex(&ctx, hash, &num_hash_bytes), 1); 136 hash->end(hash_context, digest, &num_hash_bytes, sizeof(digest));
133 137
134 uint32 todo = cipher_key_length - done; 138 unsigned todo = cipher_key_length - done;
135 if (todo > num_hash_bytes) 139 if (todo > num_hash_bytes)
136 todo = num_hash_bytes; 140 todo = num_hash_bytes;
137 memcpy(out_key + done, hash, todo); 141 memcpy(out_key + done, digest, todo);
138 done += todo; 142 done += todo;
139 } 143 }
140 144
141 EVP_MD_CTX_cleanup(&context); 145 hash->destroy(hash_context, PR_TRUE);
142 } 146 }
143 147
148 // SetKey sets up |out_key| to be an AES context, with the given key, in ECB
149 // mode and with no IV.
150 bool SetKey(const uint8* key, unsigned key_len, ScopedPK11Context* out_key) {
wtc 2011/07/01 18:33:32 This function should be named CreateAESContext.
agl 2011/07/01 20:04:59 Done.
151 ScopedPK11Slot slot(PK11_GetBestSlot(CKM_AES_ECB, NULL));
152 if (!slot.get())
153 return false;
154 SECItem key_item;
155 key_item.type = siBuffer;
156 key_item.data = const_cast<uint8*>(key);
157 key_item.len = key_len;
158 ScopedPK11SymKey pk11_key(PK11_ImportSymKey(
159 slot.get(), CKM_AES_ECB, PK11_OriginUnwrap, CKA_ENCRYPT, &key_item,
160 NULL));
161 if (!pk11_key.get())
162 return false;
163 ScopedSECItem iv_param(PK11_ParamFromIV(CKM_AES_ECB, NULL));
164 out_key->reset(PK11_CreateContextBySymKey(CKM_AES_ECB, CKA_ENCRYPT,
165 pk11_key.get(), iv_param.get()));
166 return out_key->get() != NULL;
167 }
168
169
144 // These constants are the tag numbers for the various packet types that we 170 // These constants are the tag numbers for the various packet types that we
145 // use. 171 // use.
146 static const uint32 kSymmetricKeyEncryptedTag = 3; 172 static const unsigned kSymmetricKeyEncryptedTag = 3;
147 static const uint32 kSymmetricallyEncryptedTag = 18; 173 static const unsigned kSymmetricallyEncryptedTag = 18;
148 static const uint32 kCompressedTag = 8; 174 static const unsigned kCompressedTag = 8;
149 static const uint32 kLiteralDataTag = 11; 175 static const unsigned kLiteralDataTag = 11;
150 176
151 class Decrypter { 177 class Decrypter {
152 public: 178 public:
153 ~Decrypter() { 179 ~Decrypter() {
154 for (std::vector<void*>::iterator 180 for (std::vector<void*>::iterator
155 i = arena_.begin(); i != arena_.end(); i++) { 181 i = arena_.begin(); i != arena_.end(); i++) {
156 free(*i); 182 free(*i);
157 } 183 }
158 arena_.clear(); 184 arena_.clear();
159 } 185 }
160 186
161 OpenPGPSymmetricEncrytion::Result Decrypt(base::StringPiece in, 187 OpenPGPSymmetricEncrytion::Result Decrypt(base::StringPiece in,
162 base::StringPiece passphrase, 188 base::StringPiece passphrase,
163 base::StringPiece *out_contents) { 189 base::StringPiece *out_contents) {
164 Reader reader(in); 190 Reader reader(in);
165 uint32 tag; 191 unsigned tag;
166 base::StringPiece contents; 192 base::StringPiece contents;
167 AES_KEY key; 193 ScopedPK11Context key;
wtc 2011/07/01 18:33:32 "key" is a strange name for a PK11Context. I thin
agl 2011/07/01 20:04:59 Done.
168 194
169 if (!ParsePacket(&reader, &tag, &contents)) 195 if (!ParsePacket(&reader, &tag, &contents))
170 return OpenPGPSymmetricEncrytion::PARSE_ERROR; 196 return OpenPGPSymmetricEncrytion::PARSE_ERROR;
171 if (tag != kSymmetricKeyEncryptedTag) 197 if (tag != kSymmetricKeyEncryptedTag)
172 return OpenPGPSymmetricEncrytion::NOT_SYMMETRICALLY_ENCRYPTED; 198 return OpenPGPSymmetricEncrytion::NOT_SYMMETRICALLY_ENCRYPTED;
173 Reader inner(contents); 199 Reader inner(contents);
174 OpenPGPSymmetricEncrytion::Result result = 200 OpenPGPSymmetricEncrytion::Result result =
175 ParseSymmetricKeyEncrypted(&inner, passphrase, &key); 201 ParseSymmetricKeyEncrypted(&inner, passphrase, &key);
176 if (result != OpenPGPSymmetricEncrytion::OK) 202 if (result != OpenPGPSymmetricEncrytion::OK)
177 return result; 203 return result;
(...skipping 19 matching lines...) Expand all
197 if (!ParseLiteralData(&inner, out_contents)) 223 if (!ParseLiteralData(&inner, out_contents))
198 return OpenPGPSymmetricEncrytion::PARSE_ERROR; 224 return OpenPGPSymmetricEncrytion::PARSE_ERROR;
199 225
200 return OpenPGPSymmetricEncrytion::OK; 226 return OpenPGPSymmetricEncrytion::OK;
201 } 227 }
202 228
203 private: 229 private:
204 // ParsePacket parses an OpenPGP packet from reader. See RFC 4880, section 230 // ParsePacket parses an OpenPGP packet from reader. See RFC 4880, section
205 // 4.2.2. 231 // 4.2.2.
206 bool ParsePacket(Reader *reader, 232 bool ParsePacket(Reader *reader,
207 uint32 *out_tag, 233 unsigned *out_tag,
208 base::StringPiece *out_contents) { 234 base::StringPiece *out_contents) {
209 uint8 header; 235 uint8 header;
210 if (!reader->U8(&header)) 236 if (!reader->U8(&header))
211 return false; 237 return false;
212 if ((header & 0x80) == 0) { 238 if ((header & 0x80) == 0) {
213 // Tag byte must have MSB set. 239 // Tag byte must have MSB set.
214 return false; 240 return false;
215 } 241 }
216 242
217 if ((header & 0x40) == 0) { 243 if ((header & 0x40) == 0) {
218 // Old format packet. 244 // Old format packet.
219 *out_tag = (header & 0x3f) >> 2; 245 *out_tag = (header & 0x3f) >> 2;
220 246
221 uint8 length_type = header & 3; 247 uint8 length_type = header & 3;
222 if (length_type == 3) { 248 if (length_type == 3) {
223 *out_contents = reader->Remainder(); 249 *out_contents = reader->Remainder();
224 return true; 250 return true;
225 } 251 }
226 252
227 const uint32 length_bytes = 1 << length_type; 253 const unsigned length_bytes = 1 << length_type;
228 uint32 length = 0; 254 size_t length = 0;
229 for (uint32 i = 0; i < length_bytes; i++) { 255 for (unsigned i = 0; i < length_bytes; i++) {
230 uint8 length_byte; 256 uint8 length_byte;
231 if (!reader->U8(&length_byte)) 257 if (!reader->U8(&length_byte))
232 return false; 258 return false;
233 length <<= 8; 259 length <<= 8;
234 length |= length_byte; 260 length |= length_byte;
235 } 261 }
236 262
237 return reader->Prefix(length, out_contents); 263 return reader->Prefix(length, out_contents);
238 } 264 }
239 265
240 // New format packet. 266 // New format packet.
241 *out_tag = header & 0x3f; 267 *out_tag = header & 0x3f;
242 uint32 length; 268 size_t length;
243 bool is_partial; 269 bool is_partial;
244 if (!ParseLength(reader, &length, &is_partial)) 270 if (!ParseLength(reader, &length, &is_partial))
245 return false; 271 return false;
246 if (is_partial) 272 if (is_partial)
247 return ParseStreamContents(reader, length, out_contents); 273 return ParseStreamContents(reader, length, out_contents);
248 return reader->Prefix(length, out_contents); 274 return reader->Prefix(length, out_contents);
249 } 275 }
250 276
251 // ParseStreamContents parses all the chunks of a partial length stream from 277 // ParseStreamContents parses all the chunks of a partial length stream from
252 // reader. See http://tools.ietf.org/html/rfc4880#section-4.2.2.4 278 // reader. See http://tools.ietf.org/html/rfc4880#section-4.2.2.4
253 bool ParseStreamContents(Reader *reader, 279 bool ParseStreamContents(Reader *reader,
254 uint32 length, 280 size_t length,
255 base::StringPiece *out_contents) { 281 base::StringPiece *out_contents) {
256 const Reader::Position beginning_of_stream = reader->tell(); 282 const Reader::Position beginning_of_stream = reader->tell();
257 const uint32 first_chunk_length = length; 283 const size_t first_chunk_length = length;
258 284
259 // First we parse the stream to find its length. 285 // First we parse the stream to find its length.
260 if (!reader->Skip(length)) 286 if (!reader->Skip(length))
261 return false; 287 return false;
262 288
263 for (;;) { 289 for (;;) {
264 uint32 chunk_length; 290 size_t chunk_length;
265 bool is_partial; 291 bool is_partial;
266 292
267 if (!ParseLength(reader, &chunk_length, &is_partial)) 293 if (!ParseLength(reader, &chunk_length, &is_partial))
268 return false; 294 return false;
269 if (length + chunk_length < length) 295 if (length + chunk_length < length)
270 return false; 296 return false;
271 length += chunk_length; 297 length += chunk_length;
272 if (!reader->Skip(chunk_length)) 298 if (!reader->Skip(chunk_length))
273 return false; 299 return false;
274 if (!is_partial) 300 if (!is_partial)
275 break; 301 break;
276 } 302 }
277 303
278 // Now we have the length of the whole stream in |length|. 304 // Now we have the length of the whole stream in |length|.
279 char* buf = reinterpret_cast<char*>(malloc(length)); 305 char* buf = reinterpret_cast<char*>(malloc(length));
280 arena_.push_back(buf); 306 arena_.push_back(buf);
281 uint32 j = 0; 307 size_t j = 0;
282 reader->Seek(beginning_of_stream); 308 reader->Seek(beginning_of_stream);
283 309
284 base::StringPiece first_chunk; 310 base::StringPiece first_chunk;
285 if (!reader->Prefix(first_chunk_length, &first_chunk)) 311 if (!reader->Prefix(first_chunk_length, &first_chunk))
286 return false; 312 return false;
287 memcpy(buf + j, first_chunk.data(), first_chunk_length); 313 memcpy(buf + j, first_chunk.data(), first_chunk_length);
288 j += first_chunk_length; 314 j += first_chunk_length;
289 315
290 // Now we parse the stream again, this time copying into |buf| 316 // Now we parse the stream again, this time copying into |buf|
291 for (;;) { 317 for (;;) {
292 uint32 chunk_length; 318 size_t chunk_length;
293 bool is_partial; 319 bool is_partial;
294 320
295 if (!ParseLength(reader, &chunk_length, &is_partial)) 321 if (!ParseLength(reader, &chunk_length, &is_partial))
296 return false; 322 return false;
297 base::StringPiece chunk; 323 base::StringPiece chunk;
298 if (!reader->Prefix(chunk_length, &chunk)) 324 if (!reader->Prefix(chunk_length, &chunk))
299 return false; 325 return false;
300 memcpy(buf + j, chunk.data(), chunk_length); 326 memcpy(buf + j, chunk.data(), chunk_length);
301 j += chunk_length; 327 j += chunk_length;
302 if (!is_partial) 328 if (!is_partial)
303 break; 329 break;
304 } 330 }
305 331
306 *out_contents = base::StringPiece(buf, length); 332 *out_contents = base::StringPiece(buf, length);
307 return true; 333 return true;
308 } 334 }
309 335
310 // ParseLength parses an OpenPGP length from reader. See RFC 4880, section 336 // ParseLength parses an OpenPGP length from reader. See RFC 4880, section
311 // 4.2.2. 337 // 4.2.2.
312 bool ParseLength(Reader *reader, uint32 *out_length, bool *out_is_prefix) { 338 bool ParseLength(Reader *reader, size_t *out_length, bool *out_is_prefix) {
313 uint8 length_spec; 339 uint8 length_spec;
314 if (!reader->U8(&length_spec)) 340 if (!reader->U8(&length_spec))
315 return false; 341 return false;
316 342
317 *out_is_prefix = false; 343 *out_is_prefix = false;
318 if (length_spec < 192) { 344 if (length_spec < 192) {
319 *out_length = length_spec; 345 *out_length = length_spec;
320 return true; 346 return true;
321 } else if (length_spec < 224) { 347 } else if (length_spec < 224) {
322 uint8 next_byte; 348 uint8 next_byte;
323 if (!reader->U8(&next_byte)) 349 if (!reader->U8(&next_byte))
324 return false; 350 return false;
325 351
326 *out_length = (length_spec - 192) << 8; 352 *out_length = (length_spec - 192) << 8;
327 *out_length += next_byte; 353 *out_length += next_byte;
328 return true; 354 return true;
329 } else if (length_spec < 255) { 355 } else if (length_spec < 255) {
330 *out_length = 1u << (length_spec & 0x1f); 356 *out_length = 1u << (length_spec & 0x1f);
331 *out_is_prefix = true; 357 *out_is_prefix = true;
332 return true; 358 return true;
333 } else { 359 } else {
334 return reader->U32(out_length); 360 uint32 length32;
361 return reader->U32(&length32);
362 *out_length = length32;
wtc 2011/07/01 18:33:32 BUG: this is after the return statement. I think
agl 2011/07/01 20:04:59 Thanks!
335 } 363 }
336 } 364 }
337 365
338 // ParseSymmetricKeyEncrypted parses a passphrase protected session key. See 366 // ParseSymmetricKeyEncrypted parses a passphrase protected session key. See
339 // RFC 4880, section 5.3. 367 // RFC 4880, section 5.3.
340 OpenPGPSymmetricEncrytion::Result ParseSymmetricKeyEncrypted( 368 OpenPGPSymmetricEncrytion::Result ParseSymmetricKeyEncrypted(
341 Reader *reader, 369 Reader *reader,
342 base::StringPiece passphrase, 370 base::StringPiece passphrase,
343 AES_KEY *out_key) { 371 ScopedPK11Context *out_key) {
344 uint8 version, cipher, s2k_type, hash_func_id; 372 uint8 version, cipher, s2k_type, hash_func_id;
345 if (!reader->U8(&version) || version != 4) 373 if (!reader->U8(&version) || version != 4)
346 return OpenPGPSymmetricEncrytion::PARSE_ERROR; 374 return OpenPGPSymmetricEncrytion::PARSE_ERROR;
347 375
348 if (!reader->U8(&cipher) || 376 if (!reader->U8(&cipher) ||
349 !reader->U8(&s2k_type) || 377 !reader->U8(&s2k_type) ||
350 !reader->U8(&hash_func_id)) { 378 !reader->U8(&hash_func_id)) {
351 return OpenPGPSymmetricEncrytion::PARSE_ERROR; 379 return OpenPGPSymmetricEncrytion::PARSE_ERROR;
352 } 380 }
353 381
354 uint8 cipher_key_length = OpenPGPCipherIdToKeyLength(cipher); 382 uint8 cipher_key_length = OpenPGPCipherIdToKeyLength(cipher);
355 if (cipher_key_length == 0) 383 if (cipher_key_length == 0)
356 return OpenPGPSymmetricEncrytion::UNKNOWN_CIPHER; 384 return OpenPGPSymmetricEncrytion::UNKNOWN_CIPHER;
357 385
358 const EVP_MD *hash_function; 386 HASH_HashType hash_function;
359 switch (hash_func_id) { 387 switch (hash_func_id) {
360 case 2: // SHA-1 388 case 2: // SHA-1
361 hash_function = EVP_sha1(); 389 hash_function = HASH_AlgSHA1;
362 break; 390 break;
363 case 8: // SHA-256 391 case 8: // SHA-256
364 hash_function = EVP_sha256(); 392 hash_function = HASH_AlgSHA256;
365 break; 393 break;
366 default: 394 default:
367 return OpenPGPSymmetricEncrytion::UNKNOWN_HASH; 395 return OpenPGPSymmetricEncrytion::UNKNOWN_HASH;
368 } 396 }
369 397
398 // This chunk of code parses the S2K specifier. See RFC 4880, section 3.7.1.
370 base::StringPiece salt; 399 base::StringPiece salt;
371 uint8 key[32]; 400 uint8 key[32];
372 uint8 count_spec; 401 uint8 count_spec;
373 switch (s2k_type) { 402 switch (s2k_type) {
374 case 1: 403 case 1:
375 if (!reader->Prefix(8, &salt)) 404 if (!reader->Prefix(8, &salt))
376 return OpenPGPSymmetricEncrytion::PARSE_ERROR; 405 return OpenPGPSymmetricEncrytion::PARSE_ERROR;
406 // fallthrough
wtc 2011/07/01 18:33:32 Nit: fallthrough => Fall through.
agl 2011/07/01 20:04:59 Done.
377 case 0: 407 case 0:
378 SaltedIteratedS2K(cipher_key_length, hash_function, passphrase, salt, 408 SaltedIteratedS2K(cipher_key_length, hash_function, passphrase, salt,
379 passphrase.size() + salt.size(), key); 409 passphrase.size() + salt.size(), key);
380 break; 410 break;
381 case 3: 411 case 3:
382 if (!reader->Prefix(8, &salt) || 412 if (!reader->Prefix(8, &salt) ||
383 !reader->U8(&count_spec)) { 413 !reader->U8(&count_spec)) {
384 return OpenPGPSymmetricEncrytion::PARSE_ERROR; 414 return OpenPGPSymmetricEncrytion::PARSE_ERROR;
385 } 415 }
386 SaltedIteratedS2K( 416 SaltedIteratedS2K(
387 cipher_key_length, hash_function, passphrase, salt, 417 cipher_key_length, hash_function, passphrase, salt,
388 static_cast<uint32>( 418 static_cast<unsigned>(
389 16 + (count_spec&15)) << ((count_spec >> 4) + 6), key); 419 16 + (count_spec&15)) << ((count_spec >> 4) + 6), key);
390 break; 420 break;
391 default: 421 default:
392 return OpenPGPSymmetricEncrytion::PARSE_ERROR; 422 return OpenPGPSymmetricEncrytion::PARSE_ERROR;
393 } 423 }
394 424
395 if (AES_set_encrypt_key(key, 8 * cipher_key_length, out_key)) 425 if (!SetKey(key, cipher_key_length, out_key))
396 return OpenPGPSymmetricEncrytion::INTERNAL_ERROR; 426 return OpenPGPSymmetricEncrytion::INTERNAL_ERROR;
397 427
398 if (reader->empty()) { 428 if (reader->empty()) {
399 // The resulting key is used directly. 429 // The resulting key is used directly.
400 return OpenPGPSymmetricEncrytion::OK; 430 return OpenPGPSymmetricEncrytion::OK;
401 } 431 }
402 432
403 // The S2K derived key encrypts another key that follows: 433 // The S2K derived key encrypts another key that follows:
404 base::StringPiece encrypted_key = reader->Remainder(); 434 base::StringPiece encrypted_key = reader->Remainder();
405 if (encrypted_key.size() < 1) 435 if (encrypted_key.size() < 1)
406 return OpenPGPSymmetricEncrytion::PARSE_ERROR; 436 return OpenPGPSymmetricEncrytion::PARSE_ERROR;
407 437
408 uint8* plaintext_key = reinterpret_cast<uint8*>( 438 uint8* plaintext_key = reinterpret_cast<uint8*>(
409 malloc(encrypted_key.size())); 439 malloc(encrypted_key.size()));
410 arena_.push_back(plaintext_key); 440 arena_.push_back(plaintext_key);
411 441
412 int num = 0; 442 CFBDecrypt(encrypted_key, out_key, plaintext_key);
413 uint8 iv[16] = {0};
414
415 AES_cfb128_encrypt(reinterpret_cast<const uint8*>(encrypted_key.data()),
416 plaintext_key,
417 encrypted_key.size(),
418 out_key,
419 iv,
420 &num,
421 AES_DECRYPT);
422 443
423 cipher_key_length = OpenPGPCipherIdToKeyLength(plaintext_key[0]); 444 cipher_key_length = OpenPGPCipherIdToKeyLength(plaintext_key[0]);
424 if (cipher_key_length == 0) 445 if (cipher_key_length == 0)
425 return OpenPGPSymmetricEncrytion::UNKNOWN_CIPHER; 446 return OpenPGPSymmetricEncrytion::UNKNOWN_CIPHER;
426 if (encrypted_key.size() != 1u + cipher_key_length) 447 if (encrypted_key.size() != 1u + cipher_key_length)
427 return OpenPGPSymmetricEncrytion::PARSE_ERROR; 448 return OpenPGPSymmetricEncrytion::PARSE_ERROR;
428 if (AES_set_encrypt_key(plaintext_key + 1, 8 * cipher_key_length, 449 if (!SetKey(plaintext_key + 1, cipher_key_length, out_key))
429 out_key)) {
430 return OpenPGPSymmetricEncrytion::INTERNAL_ERROR; 450 return OpenPGPSymmetricEncrytion::INTERNAL_ERROR;
431 }
432 return OpenPGPSymmetricEncrytion::OK; 451 return OpenPGPSymmetricEncrytion::OK;
433 } 452 }
434 453
435 uint32 OpenPGPCipherIdToKeyLength(uint8 cipher) { 454 // CFBDecrypt decrypts the cipher-feedback encrypted data in |in| to |out|
455 // using |key| and assumes an IV of all zeros.
456 void CFBDecrypt(base::StringPiece in, ScopedPK11Context* key, uint8* out) {
457 // We need this for PK11_CipherOp to write to, but we never check it as we
458 // work in ECB mode, one block at a time.
459 int out_len;
460
461 uint8 mask[AES_BLOCK_SIZE];
462 memset(mask, 0, sizeof(mask));
463
464 unsigned used = AES_BLOCK_SIZE;
465
466 for (size_t i = 0; i < in.size(); i++) {
467 if (used == AES_BLOCK_SIZE) {
468 PK11_CipherOp(key->get(), mask, &out_len, sizeof(mask), mask,
469 AES_BLOCK_SIZE);
470 used = 0;
471 }
472
473 uint8 t = in[i];
474 out[i] = t ^ mask[used];
475 mask[used] = t;
476 used++;
477 }
478 }
479
480 // OpenPGPCipherIdToKeyLength converts an OpenPGP cipher id (see RFC 4880,
481 // section 9.2) to the key length of that cipher. It returns 0 on error.
482 unsigned OpenPGPCipherIdToKeyLength(uint8 cipher) {
436 switch (cipher) { 483 switch (cipher) {
437 case 7: // AES-128 484 case 7: // AES-128
438 return 16; 485 return 16;
439 case 8: // AES-192 486 case 8: // AES-192
440 return 24; 487 return 24;
441 case 9: // AES-256 488 case 9: // AES-256
442 return 32; 489 return 32;
443 default: 490 default:
444 return 0; 491 return 0;
445 } 492 }
446 } 493 }
447 494
448 // ParseSymmetricallyEncrypted parses a Symmetrically Encrypted packet. See 495 // ParseSymmetricallyEncrypted parses a Symmetrically Encrypted packet. See
449 // RFC 4880, sections 5.7 and 5.13. 496 // RFC 4880, sections 5.7 and 5.13.
450 bool ParseSymmetricallyEncrypted(Reader *reader, 497 bool ParseSymmetricallyEncrypted(Reader *reader,
451 AES_KEY *key, 498 ScopedPK11Context *key,
452 base::StringPiece *out_plaintext) { 499 base::StringPiece *out_plaintext) {
500 // We need this for PK11_CipherOp to write to, but we never check it as we
501 // work in ECB mode, one block at a time.
502 int out_len;
503
453 uint8 version; 504 uint8 version;
454 if (!reader->U8(&version) || version != 1) 505 if (!reader->U8(&version) || version != 1)
455 return false; 506 return false;
456 507
457 base::StringPiece prefix_sp; 508 base::StringPiece prefix_sp;
458 if (!reader->Prefix(AES_BLOCK_SIZE + 2, &prefix_sp)) 509 if (!reader->Prefix(AES_BLOCK_SIZE + 2, &prefix_sp))
459 return false; 510 return false;
460 uint8 prefix[AES_BLOCK_SIZE + 2]; 511 uint8 prefix[AES_BLOCK_SIZE + 2];
461 memcpy(prefix, prefix_sp.data(), sizeof(prefix)); 512 memcpy(prefix, prefix_sp.data(), sizeof(prefix));
462 513
463 uint8 prefix_copy[AES_BLOCK_SIZE + 2]; 514 uint8 prefix_copy[AES_BLOCK_SIZE + 2];
464 uint8 fre[AES_BLOCK_SIZE]; 515 uint8 fre[AES_BLOCK_SIZE];
465 516
466 memset(prefix_copy, 0, AES_BLOCK_SIZE); 517 memset(prefix_copy, 0, AES_BLOCK_SIZE);
467 AES_ecb_encrypt(prefix_copy, fre, key, AES_ENCRYPT); 518 PK11_CipherOp(key->get(), fre, &out_len, sizeof(fre), prefix_copy,
468 for (uint32 i = 0; i < AES_BLOCK_SIZE; i++) 519 AES_BLOCK_SIZE);
520 for (unsigned i = 0; i < AES_BLOCK_SIZE; i++)
469 prefix_copy[i] = fre[i] ^ prefix[i]; 521 prefix_copy[i] = fre[i] ^ prefix[i];
470 AES_ecb_encrypt(prefix, fre, key, AES_ENCRYPT); 522 PK11_CipherOp(key->get(), fre, &out_len, sizeof(fre), prefix,
523 AES_BLOCK_SIZE);
471 prefix_copy[AES_BLOCK_SIZE] = prefix[AES_BLOCK_SIZE] ^ fre[0]; 524 prefix_copy[AES_BLOCK_SIZE] = prefix[AES_BLOCK_SIZE] ^ fre[0];
472 prefix_copy[AES_BLOCK_SIZE + 1] = prefix[AES_BLOCK_SIZE + 1] ^ fre[1]; 525 prefix_copy[AES_BLOCK_SIZE + 1] = prefix[AES_BLOCK_SIZE + 1] ^ fre[1];
473 526
474 if (prefix_copy[AES_BLOCK_SIZE - 2] != prefix_copy[AES_BLOCK_SIZE] || 527 if (prefix_copy[AES_BLOCK_SIZE - 2] != prefix_copy[AES_BLOCK_SIZE] ||
475 prefix_copy[AES_BLOCK_SIZE - 1] != prefix_copy[AES_BLOCK_SIZE + 1]) { 528 prefix_copy[AES_BLOCK_SIZE - 1] != prefix_copy[AES_BLOCK_SIZE + 1]) {
476 return false; 529 return false;
477 } 530 }
478 531
479 fre[0] = prefix[AES_BLOCK_SIZE]; 532 fre[0] = prefix[AES_BLOCK_SIZE];
480 fre[1] = prefix[AES_BLOCK_SIZE + 1]; 533 fre[1] = prefix[AES_BLOCK_SIZE + 1];
481 534
482 uint32 out_used = 2; 535 unsigned out_used = 2;
483 536
484 const uint32 plaintext_size = reader->size(); 537 const size_t plaintext_size = reader->size();
485 if (plaintext_size < SHA_DIGEST_LENGTH + 2) { 538 if (plaintext_size < SHA1_LENGTH + 2) {
486 // Too small to contain an MDC trailer. 539 // Too small to contain an MDC trailer.
487 return false; 540 return false;
488 } 541 }
489 542
490 uint8* plaintext = reinterpret_cast<uint8*>(malloc(plaintext_size)); 543 uint8* plaintext = reinterpret_cast<uint8*>(malloc(plaintext_size));
491 arena_.push_back(plaintext); 544 arena_.push_back(plaintext);
492 545
493 for (uint32 i = 0; i < plaintext_size; i++) { 546 for (size_t i = 0; i < plaintext_size; i++) {
494 uint8 b; 547 uint8 b;
495 if (!reader->U8(&b)) 548 if (!reader->U8(&b))
496 return false; 549 return false;
497 if (out_used == AES_BLOCK_SIZE) { 550 if (out_used == AES_BLOCK_SIZE) {
498 AES_ecb_encrypt(fre, fre, key, AES_ENCRYPT); 551 PK11_CipherOp(key->get(), fre, &out_len, sizeof(fre), fre,
552 AES_BLOCK_SIZE);
499 out_used = 0; 553 out_used = 0;
500 } 554 }
501 555
502 plaintext[i] = b ^ fre[out_used]; 556 plaintext[i] = b ^ fre[out_used];
503 fre[out_used++] = b; 557 fre[out_used++] = b;
504 } 558 }
505 559
506 // The plaintext should be followed by a Modification Detection Code 560 // The plaintext should be followed by a Modification Detection Code
507 // packet. This packet is specified such that the header is always 561 // packet. This packet is specified such that the header is always
508 // serialized as exactly these two bytes: 562 // serialized as exactly these two bytes:
509 if (plaintext[plaintext_size - SHA_DIGEST_LENGTH - 2] != 0xd3 || 563 if (plaintext[plaintext_size - SHA1_LENGTH - 2] != 0xd3 ||
510 plaintext[plaintext_size - SHA_DIGEST_LENGTH - 1] != 0x14) { 564 plaintext[plaintext_size - SHA1_LENGTH - 1] != 0x14) {
511 return false; 565 return false;
512 } 566 }
513 567
514 SHA_CTX sha1; 568 const struct SECHashObjectStr* hash = HASH_GetHashObject(HASH_AlgSHA1);
515 SHA1_Init(&sha1); 569 void* hash_context = hash->create();
516 SHA1_Update(&sha1, prefix_copy, sizeof(prefix_copy)); 570 hash->begin(hash_context);
517 SHA1_Update(&sha1, plaintext, plaintext_size - SHA_DIGEST_LENGTH); 571 hash->update(hash_context, prefix_copy, sizeof(prefix_copy));
518 uint8 digest[SHA_DIGEST_LENGTH]; 572 hash->update(hash_context, plaintext, plaintext_size - SHA1_LENGTH);
519 SHA1_Final(digest, &sha1); 573 uint8 digest[SHA1_LENGTH];
574 unsigned num_hash_bytes;
575 hash->end(hash_context, digest, &num_hash_bytes, sizeof(digest));
576 hash->destroy(hash_context, PR_TRUE);
520 577
521 if (memcmp(digest, &plaintext[plaintext_size - SHA_DIGEST_LENGTH], 578 if (memcmp(digest, &plaintext[plaintext_size - SHA1_LENGTH],
522 SHA_DIGEST_LENGTH) != 0) { 579 SHA1_LENGTH) != 0) {
523 return false; 580 return false;
524 } 581 }
525 582
526 *out_plaintext = base::StringPiece(reinterpret_cast<char*>(plaintext), 583 *out_plaintext = base::StringPiece(reinterpret_cast<char*>(plaintext),
527 plaintext_size - SHA_DIGEST_LENGTH); 584 plaintext_size - SHA1_LENGTH);
528 return true; 585 return true;
529 } 586 }
530 587
531 // ParseLiteralData parses a Literal Data packet. See RFC 4880, section 5.9. 588 // ParseLiteralData parses a Literal Data packet. See RFC 4880, section 5.9.
532 bool ParseLiteralData(Reader *reader, base::StringPiece *out_data) { 589 bool ParseLiteralData(Reader *reader, base::StringPiece *out_data) {
533 uint8 is_binary, filename_len; 590 uint8 is_binary, filename_len;
534 if (!reader->U8(&is_binary) || 591 if (!reader->U8(&is_binary) ||
535 !reader->U8(&filename_len) || 592 !reader->U8(&filename_len) ||
536 !reader->Skip(filename_len) || 593 !reader->Skip(filename_len) ||
537 !reader->Skip(sizeof(uint32) /* mtime */)) { 594 !reader->Skip(sizeof(uint32) /* mtime */)) {
(...skipping 19 matching lines...) Expand all
557 base::StringPiece passphrase) { 614 base::StringPiece passphrase) {
558 ByteString key; 615 ByteString key;
559 ByteString ske = SerializeSymmetricKeyEncrypted(passphrase, &key); 616 ByteString ske = SerializeSymmetricKeyEncrypted(passphrase, &key);
560 617
561 ByteString literal_data = SerializeLiteralData(plaintext); 618 ByteString literal_data = SerializeLiteralData(plaintext);
562 ByteString se = SerializeSymmetricallyEncrypted(literal_data, key); 619 ByteString se = SerializeSymmetricallyEncrypted(literal_data, key);
563 return ske + se; 620 return ske + se;
564 } 621 }
565 622
566 private: 623 private:
567 static ByteString MakePacket(uint32 tag, const ByteString& contents) { 624 // MakePacket returns an OpenPGP packet tagged as type |tag|. It always uses
625 // new-format headers. See RFC 4880, section 4.2.
626 static ByteString MakePacket(unsigned tag, const ByteString& contents) {
568 ByteString header; 627 ByteString header;
569 header.push_back(0x80 | 0x40 | tag); 628 header.push_back(0x80 | 0x40 | tag);
570 629
571 if (contents.size() < 192) { 630 if (contents.size() < 192) {
572 header.push_back(contents.size()); 631 header.push_back(contents.size());
573 } else if (contents.size() < 8384) { 632 } else if (contents.size() < 8384) {
574 size_t length = contents.size(); 633 size_t length = contents.size();
575 length -= 192; 634 length -= 192;
576 header.push_back(192 + (length >> 8)); 635 header.push_back(192 + (length >> 8));
577 header.push_back(length & 0xff); 636 header.push_back(length & 0xff);
578 } else { 637 } else {
579 size_t length = contents.size(); 638 size_t length = contents.size();
580 header.push_back(255); 639 header.push_back(255);
581 header.push_back(length >> 24); 640 header.push_back(length >> 24);
582 header.push_back(length >> 16); 641 header.push_back(length >> 16);
583 header.push_back(length >> 8); 642 header.push_back(length >> 8);
584 header.push_back(length); 643 header.push_back(length);
585 } 644 }
586 645
587 return header + contents; 646 return header + contents;
588 } 647 }
589 648
649 // SerializeLiteralData returns a Literal Data packet containing |contents|
650 // as binary data with no filename nor mtime specified. See RFC 4880, section
651 // 5.9.
590 static ByteString SerializeLiteralData(base::StringPiece contents) { 652 static ByteString SerializeLiteralData(base::StringPiece contents) {
591 ByteString literal_data; 653 ByteString literal_data;
592 literal_data.push_back(0x74); // text mode 654 literal_data.push_back(0x74); // text mode
593 literal_data.push_back(0x00); // no filename 655 literal_data.push_back(0x00); // no filename
594 literal_data.push_back(0x00); // zero mtime 656 literal_data.push_back(0x00); // zero mtime
595 literal_data.push_back(0x00); 657 literal_data.push_back(0x00);
596 literal_data.push_back(0x00); 658 literal_data.push_back(0x00);
597 literal_data.push_back(0x00); 659 literal_data.push_back(0x00);
598 literal_data += ByteString(reinterpret_cast<const uint8*>(contents.data()), 660 literal_data += ByteString(reinterpret_cast<const uint8*>(contents.data()),
599 contents.size()); 661 contents.size());
600 return MakePacket(kLiteralDataTag, literal_data); 662 return MakePacket(kLiteralDataTag, literal_data);
601 } 663 }
602 664
665 // SerializeSymmetricKeyEncrypted generates a random AES-128 key from
666 // |passphrase|, sets |out_key| to it and returns a Symmetric Key Encrypted
667 // packet. See RFC 4880, section 5.3.
603 static ByteString SerializeSymmetricKeyEncrypted(base::StringPiece passphrase, 668 static ByteString SerializeSymmetricKeyEncrypted(base::StringPiece passphrase,
604 ByteString *out_key) { 669 ByteString *out_key) {
605 ByteString ske; 670 ByteString ske;
606 ske.push_back(4); // version 4 671 ske.push_back(4); // version 4
607 ske.push_back(7); // AES-128 672 ske.push_back(7); // AES-128
608 ske.push_back(3); // iterated and salted S2K 673 ske.push_back(3); // iterated and salted S2K
609 ske.push_back(2); // SHA-1 674 ske.push_back(2); // SHA-1
610 675
611 uint64 salt64 = base::RandUint64(); 676 uint64 salt64 = base::RandUint64();
612 ByteString salt(sizeof(salt64), 0); 677 ByteString salt(sizeof(salt64), 0);
613 678
614 // It's a random value, so endianness doesn't matter. 679 // It's a random value, so endianness doesn't matter.
615 ske += ByteString(reinterpret_cast<uint8*>(&salt64), sizeof(salt64)); 680 ske += ByteString(reinterpret_cast<uint8*>(&salt64), sizeof(salt64));
616 ske.push_back(96); // iteration count of 65536 681 ske.push_back(96); // iteration count of 65536
617 682
618 uint8 key[16]; 683 uint8 key[16];
619 SaltedIteratedS2K( 684 SaltedIteratedS2K(
620 sizeof(key), EVP_sha1(), passphrase, 685 sizeof(key), HASH_AlgSHA1, passphrase,
621 base::StringPiece(reinterpret_cast<char*>(&salt64), sizeof(salt64)), 686 base::StringPiece(reinterpret_cast<char*>(&salt64), sizeof(salt64)),
622 65536, key); 687 65536, key);
623 *out_key = ByteString(key, sizeof(key)); 688 *out_key = ByteString(key, sizeof(key));
624 return MakePacket(kSymmetricKeyEncryptedTag, ske); 689 return MakePacket(kSymmetricKeyEncryptedTag, ske);
625 } 690 }
626 691
692 // SerializeSymmetricallyEncrypted encrypts |plaintext| with |key| and
693 // returns a Symmetrically Encrypted packet containing the ciphertext. See
694 // RFC 4880, section 5.7.
627 static ByteString SerializeSymmetricallyEncrypted(ByteString plaintext, 695 static ByteString SerializeSymmetricallyEncrypted(ByteString plaintext,
628 const ByteString& key) { 696 const ByteString& key) {
697 // We need this for PK11_CipherOp to write to, but we never check it as we
698 // work in ECB mode, one block at a time.
699 int out_len;
700
629 ByteString packet; 701 ByteString packet;
630 packet.push_back(1); // version 1 702 packet.push_back(1); // version 1
631 static const uint32 kBlockSize = 16; // AES block size 703 static const unsigned kBlockSize = 16; // AES block size
632 704
633 uint8 prefix[kBlockSize + 2], fre[kBlockSize], iv[kBlockSize]; 705 uint8 prefix[kBlockSize + 2], fre[kBlockSize], iv[kBlockSize];
634 base::RandBytes(iv, kBlockSize); 706 base::RandBytes(iv, kBlockSize);
635 memset(fre, 0, sizeof(fre)); 707 memset(fre, 0, sizeof(fre));
636 708
637 AES_KEY aes_key; 709 ScopedPK11Context aes_key;
638 AES_set_encrypt_key(key.data(), 8 * key.size(), &aes_key); 710 CHECK(SetKey(key.data(), key.size(), &aes_key));
639 711
640 AES_ecb_encrypt(fre, fre, &aes_key, AES_ENCRYPT); 712 PK11_CipherOp(aes_key.get(), fre, &out_len, sizeof(fre), fre,
641 for (uint32 i = 0; i < 16; i++) 713 AES_BLOCK_SIZE);
714 for (unsigned i = 0; i < 16; i++)
642 prefix[i] = iv[i] ^ fre[i]; 715 prefix[i] = iv[i] ^ fre[i];
643 AES_ecb_encrypt(prefix, fre, &aes_key, AES_ENCRYPT); 716 PK11_CipherOp(aes_key.get(), fre, &out_len, sizeof(fre), prefix,
717 AES_BLOCK_SIZE);
644 prefix[kBlockSize] = iv[kBlockSize - 2] ^ fre[0]; 718 prefix[kBlockSize] = iv[kBlockSize - 2] ^ fre[0];
645 prefix[kBlockSize + 1] = iv[kBlockSize - 1] ^ fre[1]; 719 prefix[kBlockSize + 1] = iv[kBlockSize - 1] ^ fre[1];
646 720
647 packet += ByteString(prefix, sizeof(prefix)); 721 packet += ByteString(prefix, sizeof(prefix));
648 722
649 ByteString plaintext_copy = plaintext; 723 ByteString plaintext_copy = plaintext;
650 plaintext_copy.push_back(0xd3); // MDC packet 724 plaintext_copy.push_back(0xd3); // MDC packet
651 plaintext_copy.push_back(20); // packet length (20 bytes) 725 plaintext_copy.push_back(20); // packet length (20 bytes)
652 726
653 SHA_CTX sha1; 727 const struct SECHashObjectStr* hash = HASH_GetHashObject(HASH_AlgSHA1);
654 SHA1_Init(&sha1); 728 void* hash_context = hash->create();
655 SHA1_Update(&sha1, iv, sizeof(iv)); 729 hash->begin(hash_context);
656 SHA1_Update(&sha1, iv + kBlockSize - 2, 2); 730 hash->update(hash_context, iv, sizeof(iv));
657 SHA1_Update(&sha1, plaintext_copy.data(), plaintext_copy.size()); 731 hash->update(hash_context, iv + kBlockSize - 2, 2);
658 uint8 digest[SHA_DIGEST_LENGTH]; 732 hash->update(hash_context, plaintext_copy.data(), plaintext_copy.size());
659 SHA1_Final(digest, &sha1); 733 uint8 digest[SHA1_LENGTH];
734 unsigned num_hash_bytes;
735 hash->end(hash_context, digest, &num_hash_bytes, sizeof(digest));
736 hash->destroy(hash_context, PR_TRUE);
660 737
661 plaintext_copy += ByteString(digest, sizeof(digest)); 738 plaintext_copy += ByteString(digest, sizeof(digest));
662 739
663 fre[0] = prefix[kBlockSize]; 740 fre[0] = prefix[kBlockSize];
664 fre[1] = prefix[kBlockSize+1]; 741 fre[1] = prefix[kBlockSize+1];
665 uint32 out_used = 2; 742 unsigned out_used = 2;
666 743
667 for (size_t i = 0; i < plaintext_copy.size(); i++) { 744 for (size_t i = 0; i < plaintext_copy.size(); i++) {
668 if (out_used == kBlockSize) { 745 if (out_used == kBlockSize) {
669 AES_ecb_encrypt(fre, fre, &aes_key, AES_ENCRYPT); 746 PK11_CipherOp(aes_key.get(), fre, &out_len, sizeof(fre), fre,
747 AES_BLOCK_SIZE);
670 out_used = 0; 748 out_used = 0;
671 } 749 }
672 750
673 uint8 c = plaintext_copy[i] ^ fre[out_used]; 751 uint8 c = plaintext_copy[i] ^ fre[out_used];
674 fre[out_used++] = c; 752 fre[out_used++] = c;
675 packet.push_back(c); 753 packet.push_back(c);
676 } 754 }
677 755
678 return MakePacket(kSymmetricallyEncryptedTag, packet); 756 return MakePacket(kSymmetricallyEncryptedTag, packet);
679 } 757 }
(...skipping 18 matching lines...) Expand all
698 // static 776 // static
699 std::string OpenPGPSymmetricEncrytion::Encrypt( 777 std::string OpenPGPSymmetricEncrytion::Encrypt(
700 base::StringPiece plaintext, 778 base::StringPiece plaintext,
701 base::StringPiece passphrase) { 779 base::StringPiece passphrase) {
702 Encrypter::ByteString b = 780 Encrypter::ByteString b =
703 Encrypter::Encrypt(plaintext, passphrase); 781 Encrypter::Encrypt(plaintext, passphrase);
704 return std::string(reinterpret_cast<const char*>(b.data()), b.size()); 782 return std::string(reinterpret_cast<const char*>(b.data()), b.size());
705 } 783 }
706 784
707 } // namespace crypto 785 } // namespace crypto
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698