Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/symmetric_key.h" | 5 #include "crypto/symmetric_key.h" |
| 6 | 6 |
| 7 #include <openssl/evp.h> | 7 #include <openssl/evp.h> |
| 8 #include <openssl/rand.h> | 8 #include <openssl/rand.h> |
| 9 #include <stddef.h> | 9 #include <stddef.h> |
| 10 #include <stdint.h> | 10 #include <stdint.h> |
| 11 | 11 |
| 12 #include <algorithm> | 12 #include <algorithm> |
| 13 #include <memory> | 13 #include <memory> |
|
davidben
2016/06/23 03:09:36
Nit: already in header
| |
| 14 | 14 |
| 15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
| 17 #include "crypto/openssl_util.h" | 17 #include "crypto/openssl_util.h" |
| 18 | 18 |
| 19 namespace crypto { | 19 namespace crypto { |
| 20 | 20 |
| 21 SymmetricKey::~SymmetricKey() { | 21 SymmetricKey::~SymmetricKey() { |
| 22 std::fill(key_.begin(), key_.end(), '\0'); // Zero out the confidential key. | 22 std::fill(key_.begin(), key_.end(), '\0'); // Zero out the confidential key. |
| 23 } | 23 } |
| 24 | 24 |
| 25 // static | 25 // static |
| 26 SymmetricKey* SymmetricKey::GenerateRandomKey(Algorithm algorithm, | 26 std::unique_ptr<SymmetricKey> SymmetricKey::GenerateRandomKey( |
| 27 size_t key_size_in_bits) { | 27 Algorithm algorithm, |
| 28 size_t key_size_in_bits) { | |
| 28 DCHECK_EQ(AES, algorithm); | 29 DCHECK_EQ(AES, algorithm); |
| 29 | 30 |
| 30 // Whitelist supported key sizes to avoid accidentaly relying on | 31 // Whitelist supported key sizes to avoid accidentaly relying on |
| 31 // algorithms available in NSS but not BoringSSL and vice | 32 // algorithms available in NSS but not BoringSSL and vice |
| 32 // versa. Note that BoringSSL does not support AES-192. | 33 // versa. Note that BoringSSL does not support AES-192. |
| 33 if (key_size_in_bits != 128 && key_size_in_bits != 256) | 34 if (key_size_in_bits != 128 && key_size_in_bits != 256) |
| 34 return NULL; | 35 return nullptr; |
| 35 | 36 |
| 36 size_t key_size_in_bytes = key_size_in_bits / 8; | 37 size_t key_size_in_bytes = key_size_in_bits / 8; |
| 37 DCHECK_EQ(key_size_in_bits, key_size_in_bytes * 8); | 38 DCHECK_EQ(key_size_in_bits, key_size_in_bytes * 8); |
| 38 | 39 |
| 39 if (key_size_in_bytes == 0) | 40 if (key_size_in_bytes == 0) |
| 40 return NULL; | 41 return nullptr; |
| 41 | 42 |
| 42 OpenSSLErrStackTracer err_tracer(FROM_HERE); | 43 OpenSSLErrStackTracer err_tracer(FROM_HERE); |
| 43 std::unique_ptr<SymmetricKey> key(new SymmetricKey); | 44 std::unique_ptr<SymmetricKey> key(new SymmetricKey); |
| 44 uint8_t* key_data = reinterpret_cast<uint8_t*>( | 45 uint8_t* key_data = reinterpret_cast<uint8_t*>( |
| 45 base::WriteInto(&key->key_, key_size_in_bytes + 1)); | 46 base::WriteInto(&key->key_, key_size_in_bytes + 1)); |
| 46 | 47 |
| 47 int rv = RAND_bytes(key_data, static_cast<int>(key_size_in_bytes)); | 48 int rv = RAND_bytes(key_data, static_cast<int>(key_size_in_bytes)); |
| 48 return rv == 1 ? key.release() : NULL; | 49 return rv == 1 ? std::move(key) : nullptr; |
| 49 } | 50 } |
| 50 | 51 |
| 51 // static | 52 // static |
| 52 SymmetricKey* SymmetricKey::DeriveKeyFromPassword(Algorithm algorithm, | 53 std::unique_ptr<SymmetricKey> SymmetricKey::DeriveKeyFromPassword( |
| 53 const std::string& password, | 54 Algorithm algorithm, |
| 54 const std::string& salt, | 55 const std::string& password, |
| 55 size_t iterations, | 56 const std::string& salt, |
| 56 size_t key_size_in_bits) { | 57 size_t iterations, |
| 58 size_t key_size_in_bits) { | |
| 57 DCHECK(algorithm == AES || algorithm == HMAC_SHA1); | 59 DCHECK(algorithm == AES || algorithm == HMAC_SHA1); |
| 58 | 60 |
| 59 if (algorithm == AES) { | 61 if (algorithm == AES) { |
| 60 // Whitelist supported key sizes to avoid accidentaly relying on | 62 // Whitelist supported key sizes to avoid accidentaly relying on |
| 61 // algorithms available in NSS but not BoringSSL and vice | 63 // algorithms available in NSS but not BoringSSL and vice |
| 62 // versa. Note that BoringSSL does not support AES-192. | 64 // versa. Note that BoringSSL does not support AES-192. |
| 63 if (key_size_in_bits != 128 && key_size_in_bits != 256) | 65 if (key_size_in_bits != 128 && key_size_in_bits != 256) |
| 64 return NULL; | 66 return nullptr; |
| 65 } | 67 } |
| 66 | 68 |
| 67 size_t key_size_in_bytes = key_size_in_bits / 8; | 69 size_t key_size_in_bytes = key_size_in_bits / 8; |
| 68 DCHECK_EQ(key_size_in_bits, key_size_in_bytes * 8); | 70 DCHECK_EQ(key_size_in_bits, key_size_in_bytes * 8); |
| 69 | 71 |
| 70 if (key_size_in_bytes == 0) | 72 if (key_size_in_bytes == 0) |
| 71 return NULL; | 73 return nullptr; |
| 72 | 74 |
| 73 OpenSSLErrStackTracer err_tracer(FROM_HERE); | 75 OpenSSLErrStackTracer err_tracer(FROM_HERE); |
| 74 std::unique_ptr<SymmetricKey> key(new SymmetricKey); | 76 std::unique_ptr<SymmetricKey> key(new SymmetricKey); |
| 75 uint8_t* key_data = reinterpret_cast<uint8_t*>( | 77 uint8_t* key_data = reinterpret_cast<uint8_t*>( |
| 76 base::WriteInto(&key->key_, key_size_in_bytes + 1)); | 78 base::WriteInto(&key->key_, key_size_in_bytes + 1)); |
| 77 int rv = PKCS5_PBKDF2_HMAC_SHA1( | 79 int rv = PKCS5_PBKDF2_HMAC_SHA1( |
| 78 password.data(), password.length(), | 80 password.data(), password.length(), |
| 79 reinterpret_cast<const uint8_t*>(salt.data()), salt.length(), | 81 reinterpret_cast<const uint8_t*>(salt.data()), salt.length(), |
| 80 static_cast<unsigned>(iterations), | 82 static_cast<unsigned>(iterations), |
| 81 key_size_in_bytes, key_data); | 83 key_size_in_bytes, key_data); |
| 82 return rv == 1 ? key.release() : NULL; | 84 return rv == 1 ? std::move(key) : nullptr; |
|
davidben
2016/06/23 03:09:36
#include <utility>
| |
| 83 } | 85 } |
| 84 | 86 |
| 85 // static | 87 // static |
| 86 SymmetricKey* SymmetricKey::Import(Algorithm algorithm, | 88 std::unique_ptr<SymmetricKey> SymmetricKey::Import(Algorithm algorithm, |
| 87 const std::string& raw_key) { | 89 const std::string& raw_key) { |
| 88 if (algorithm == AES) { | 90 if (algorithm == AES) { |
| 89 // Whitelist supported key sizes to avoid accidentaly relying on | 91 // Whitelist supported key sizes to avoid accidentaly relying on |
| 90 // algorithms available in NSS but not BoringSSL and vice | 92 // algorithms available in NSS but not BoringSSL and vice |
| 91 // versa. Note that BoringSSL does not support AES-192. | 93 // versa. Note that BoringSSL does not support AES-192. |
| 92 if (raw_key.size() != 128/8 && raw_key.size() != 256/8) | 94 if (raw_key.size() != 128/8 && raw_key.size() != 256/8) |
| 93 return NULL; | 95 return nullptr; |
| 94 } | 96 } |
| 95 | 97 |
| 96 std::unique_ptr<SymmetricKey> key(new SymmetricKey); | 98 std::unique_ptr<SymmetricKey> key(new SymmetricKey); |
| 97 key->key_ = raw_key; | 99 key->key_ = raw_key; |
| 98 return key.release(); | 100 return key; |
| 99 } | 101 } |
| 100 | 102 |
| 101 bool SymmetricKey::GetRawKey(std::string* raw_key) { | 103 bool SymmetricKey::GetRawKey(std::string* raw_key) { |
| 102 *raw_key = key_; | 104 *raw_key = key_; |
| 103 return true; | 105 return true; |
| 104 } | 106 } |
| 105 | 107 |
| 108 SymmetricKey::SymmetricKey() = default; | |
|
davidben
2016/06/23 03:09:36
(Isn't this normally in the header file? Or did it
Ryan Sleevi
2016/06/23 21:47:40
It didn't run afoul - but it was close to it, and
| |
| 109 | |
| 106 } // namespace crypto | 110 } // namespace crypto |
| OLD | NEW |