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/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 int key_size_in_bytes
= key_size_in_bits
/ 8;
28 DCHECK_EQ(static_cast<int>(key_size_in_bits
), key_size_in_bytes
* 8);
30 if (key_size_in_bits
== 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
, 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 int key_size_in_bytes
= key_size_in_bits
/ 8;
50 DCHECK_EQ(static_cast<int>(key_size_in_bits
), key_size_in_bytes
* 8);
52 OpenSSLErrStackTracer
err_tracer(FROM_HERE
);
53 scoped_ptr
<SymmetricKey
> key(new SymmetricKey
);
55 reinterpret_cast<uint8
*>(WriteInto(&key
->key_
, key_size_in_bytes
+ 1));
56 int rv
= PKCS5_PBKDF2_HMAC_SHA1(password
.data(), password
.length(),
57 reinterpret_cast<const uint8
*>(salt
.data()),
58 salt
.length(), iterations
,
59 key_size_in_bytes
, key_data
);
60 return rv
== 1 ? key
.release() : NULL
;
64 SymmetricKey
* SymmetricKey::Import(Algorithm algorithm
,
65 const std::string
& raw_key
) {
66 scoped_ptr
<SymmetricKey
> key(new SymmetricKey
);
71 bool SymmetricKey::GetRawKey(std::string
* raw_key
) {