OLD | NEW |
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/symmetric_key.h" | 5 #include "crypto/symmetric_key.h" |
6 | 6 |
| 7 #include <stddef.h> |
| 8 #include <stdint.h> |
| 9 |
7 #include <vector> | 10 #include <vector> |
8 | 11 |
9 // TODO(wtc): replace scoped_array by std::vector. | 12 // TODO(wtc): replace scoped_array by std::vector. |
10 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
11 #include "base/sys_byteorder.h" | 14 #include "base/sys_byteorder.h" |
12 | 15 |
13 namespace crypto { | 16 namespace crypto { |
14 | 17 |
15 namespace { | 18 namespace { |
16 | 19 |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 // Computes a block of the derived key using the PBKDF2 function F for the | 235 // Computes a block of the derived key using the PBKDF2 function F for the |
233 // specified |block_index| using the PRF |hash|, writing the output to | 236 // specified |block_index| using the PRF |hash|, writing the output to |
234 // |output_buf|. | 237 // |output_buf|. |
235 // |output_buf| must have enough space to accomodate the output of the PRF | 238 // |output_buf| must have enough space to accomodate the output of the PRF |
236 // specified by |hash|. | 239 // specified by |hash|. |
237 // Returns true if the block was successfully computed. | 240 // Returns true if the block was successfully computed. |
238 bool ComputePBKDF2Block(HCRYPTHASH hash, | 241 bool ComputePBKDF2Block(HCRYPTHASH hash, |
239 DWORD hash_size, | 242 DWORD hash_size, |
240 const std::string& salt, | 243 const std::string& salt, |
241 size_t iterations, | 244 size_t iterations, |
242 uint32 block_index, | 245 uint32_t block_index, |
243 BYTE* output_buf) { | 246 BYTE* output_buf) { |
244 // From RFC 2898: | 247 // From RFC 2898: |
245 // 3. <snip> The function F is defined as the exclusive-or sum of the first | 248 // 3. <snip> The function F is defined as the exclusive-or sum of the first |
246 // c iterates of the underlying pseudorandom function PRF applied to the | 249 // c iterates of the underlying pseudorandom function PRF applied to the |
247 // password P and the concatenation of the salt S and the block index i: | 250 // password P and the concatenation of the salt S and the block index i: |
248 // F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c | 251 // F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c |
249 // where | 252 // where |
250 // U_1 = PRF(P, S || INT (i)) | 253 // U_1 = PRF(P, S || INT (i)) |
251 // U_2 = PRF(P, U_1) | 254 // U_2 = PRF(P, U_1) |
252 // ... | 255 // ... |
253 // U_c = PRF(P, U_{c-1}) | 256 // U_c = PRF(P, U_{c-1}) |
254 ScopedHCRYPTHASH safe_hash; | 257 ScopedHCRYPTHASH safe_hash; |
255 BOOL ok = CryptDuplicateHash(hash, NULL, 0, safe_hash.receive()); | 258 BOOL ok = CryptDuplicateHash(hash, NULL, 0, safe_hash.receive()); |
256 if (!ok) | 259 if (!ok) |
257 return false; | 260 return false; |
258 | 261 |
259 // Iteration U_1: Compute PRF for S. | 262 // Iteration U_1: Compute PRF for S. |
260 ok = CryptHashData(safe_hash, reinterpret_cast<const BYTE*>(salt.data()), | 263 ok = CryptHashData(safe_hash, reinterpret_cast<const BYTE*>(salt.data()), |
261 static_cast<DWORD>(salt.size()), 0); | 264 static_cast<DWORD>(salt.size()), 0); |
262 if (!ok) | 265 if (!ok) |
263 return false; | 266 return false; |
264 | 267 |
265 // Iteration U_1: and append (big-endian) INT (i). | 268 // Iteration U_1: and append (big-endian) INT (i). |
266 uint32 big_endian_block_index = base::HostToNet32(block_index); | 269 uint32_t big_endian_block_index = base::HostToNet32(block_index); |
267 ok = CryptHashData(safe_hash, | 270 ok = CryptHashData(safe_hash, |
268 reinterpret_cast<BYTE*>(&big_endian_block_index), | 271 reinterpret_cast<BYTE*>(&big_endian_block_index), |
269 sizeof(big_endian_block_index), 0); | 272 sizeof(big_endian_block_index), 0); |
270 | 273 |
271 std::vector<BYTE> hash_value(hash_size); | 274 std::vector<BYTE> hash_value(hash_size); |
272 | 275 |
273 DWORD size = hash_size; | 276 DWORD size = hash_size; |
274 ok = CryptGetHashParam(safe_hash, HP_HASHVAL, &hash_value[0], &size, 0); | 277 ok = CryptGetHashParam(safe_hash, HP_HASHVAL, &hash_value[0], &size, 0); |
275 if (!ok || size != hash_size) | 278 if (!ok || size != hash_size) |
276 return false; | 279 return false; |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 // to the password P, the salt S, the iteration count c, and the block | 436 // to the password P, the salt S, the iteration count c, and the block |
434 // index to compute the block: | 437 // index to compute the block: |
435 // T_1 = F (P, S, c, 1) | 438 // T_1 = F (P, S, c, 1) |
436 // T_2 = F (P, S, c, 2) | 439 // T_2 = F (P, S, c, 2) |
437 // ... | 440 // ... |
438 // T_l = F (P, S, c, l) | 441 // T_l = F (P, S, c, l) |
439 // <snip> | 442 // <snip> |
440 // 4. Concatenate the blocks and extract the first dkLen octets to produce | 443 // 4. Concatenate the blocks and extract the first dkLen octets to produce |
441 // a derived key DK: | 444 // a derived key DK: |
442 // DK = T_1 || T_2 || ... || T_l<0..r-1> | 445 // DK = T_1 || T_2 || ... || T_l<0..r-1> |
443 for (uint32 block_index = 1; block_index <= L; ++block_index) { | 446 for (uint32_t block_index = 1; block_index <= L; ++block_index) { |
444 if (!ComputePBKDF2Block(prf, hLen, salt, iterations, block_index, | 447 if (!ComputePBKDF2Block(prf, hLen, salt, iterations, block_index, |
445 block_offset)) | 448 block_offset)) |
446 return NULL; | 449 return NULL; |
447 block_offset += hLen; | 450 block_offset += hLen; |
448 } | 451 } |
449 | 452 |
450 // Convert the derived key bytes into a key handle for the desired algorithm. | 453 // Convert the derived key bytes into a key handle for the desired algorithm. |
451 ScopedHCRYPTKEY key; | 454 ScopedHCRYPTKEY key; |
452 if (!ImportRawKey(provider, alg, &generated_key[0], dkLen, &key)) | 455 if (!ImportRawKey(provider, alg, &generated_key[0], dkLen, &key)) |
453 return NULL; | 456 return NULL; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 HCRYPTKEY key, | 530 HCRYPTKEY key, |
528 const void* key_data, size_t key_size_in_bytes) | 531 const void* key_data, size_t key_size_in_bytes) |
529 : provider_(provider), key_(key) { | 532 : provider_(provider), key_(key) { |
530 if (key_data) { | 533 if (key_data) { |
531 raw_key_.assign(reinterpret_cast<const char*>(key_data), | 534 raw_key_.assign(reinterpret_cast<const char*>(key_data), |
532 key_size_in_bytes); | 535 key_size_in_bytes); |
533 } | 536 } |
534 } | 537 } |
535 | 538 |
536 } // namespace crypto | 539 } // namespace crypto |
OLD | NEW |