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 <utility> |
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; |
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; |
| 109 |
106 } // namespace crypto | 110 } // namespace crypto |
OLD | NEW |