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
3 // found in the LICENSE file.
5 #include "crypto/symmetric_key.h"
7 #include <openssl/evp.h>
8 #include <openssl/rand.h>
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/strings/string_util.h"
15 #include "crypto/openssl_util.h"
19 SymmetricKey::~SymmetricKey() {
20 std::fill(key_
.begin(), key_
.end(), '\0'); // Zero out the confidential key.
24 SymmetricKey
* SymmetricKey::GenerateRandomKey(Algorithm algorithm
,
25 size_t key_size_in_bits
) {
26 DCHECK_EQ(AES
, algorithm
);
27 size_t key_size_in_bytes
= key_size_in_bits
/ 8;
28 DCHECK_EQ(key_size_in_bits
, key_size_in_bytes
* 8);
30 if (key_size_in_bytes
== 0)
33 OpenSSLErrStackTracer
err_tracer(FROM_HERE
);
34 scoped_ptr
<SymmetricKey
> key(new SymmetricKey
);
36 reinterpret_cast<uint8
*>(WriteInto(&key
->key_
, key_size_in_bytes
+ 1));
38 int rv
= RAND_bytes(key_data
, static_cast<int>(key_size_in_bytes
));
39 return rv
== 1 ? key
.release() : NULL
;
43 SymmetricKey
* SymmetricKey::DeriveKeyFromPassword(Algorithm algorithm
,
44 const std::string
& password
,
45 const std::string
& salt
,
47 size_t key_size_in_bits
) {
48 DCHECK(algorithm
== AES
|| algorithm
== HMAC_SHA1
);
49 size_t key_size_in_bytes
= key_size_in_bits
/ 8;
50 DCHECK_EQ(key_size_in_bits
, key_size_in_bytes
* 8);
52 if (key_size_in_bytes
== 0)
55 OpenSSLErrStackTracer
err_tracer(FROM_HERE
);
56 scoped_ptr
<SymmetricKey
> key(new SymmetricKey
);
58 reinterpret_cast<uint8
*>(WriteInto(&key
->key_
, key_size_in_bytes
+ 1));
59 int rv
= PKCS5_PBKDF2_HMAC_SHA1(password
.data(), password
.length(),
60 reinterpret_cast<const uint8
*>(salt
.data()),
61 salt
.length(), iterations
,
62 static_cast<int>(key_size_in_bytes
),
64 return rv
== 1 ? key
.release() : NULL
;
68 SymmetricKey
* SymmetricKey::Import(Algorithm algorithm
,
69 const std::string
& raw_key
) {
70 scoped_ptr
<SymmetricKey
> key(new SymmetricKey
);
75 bool SymmetricKey::GetRawKey(std::string
* raw_key
) {