| 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 |