- add sources.
[platform/framework/web/crosswalk.git] / src / crypto / symmetric_key_openssl.cc
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.
4
5 #include "crypto/symmetric_key.h"
6
7 #include <openssl/evp.h>
8 #include <openssl/rand.h>
9
10 #include <algorithm>
11
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"
16
17 namespace crypto {
18
19 SymmetricKey::~SymmetricKey() {
20   std::fill(key_.begin(), key_.end(), '\0');  // Zero out the confidential key.
21 }
22
23 // static
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);
29
30   if (key_size_in_bytes == 0)
31     return NULL;
32
33   OpenSSLErrStackTracer err_tracer(FROM_HERE);
34   scoped_ptr<SymmetricKey> key(new SymmetricKey);
35   uint8* key_data =
36       reinterpret_cast<uint8*>(WriteInto(&key->key_, key_size_in_bytes + 1));
37
38   int rv = RAND_bytes(key_data, static_cast<int>(key_size_in_bytes));
39   return rv == 1 ? key.release() : NULL;
40 }
41
42 // static
43 SymmetricKey* SymmetricKey::DeriveKeyFromPassword(Algorithm algorithm,
44                                                   const std::string& password,
45                                                   const std::string& salt,
46                                                   size_t iterations,
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);
51
52   if (key_size_in_bytes == 0)
53     return NULL;
54
55   OpenSSLErrStackTracer err_tracer(FROM_HERE);
56   scoped_ptr<SymmetricKey> key(new SymmetricKey);
57   uint8* key_data =
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),
63                                   key_data);
64   return rv == 1 ? key.release() : NULL;
65 }
66
67 // static
68 SymmetricKey* SymmetricKey::Import(Algorithm algorithm,
69                                    const std::string& raw_key) {
70   scoped_ptr<SymmetricKey> key(new SymmetricKey);
71   key->key_ = raw_key;
72   return key.release();
73 }
74
75 bool SymmetricKey::GetRawKey(std::string* raw_key) {
76   *raw_key = key_;
77   return true;
78 }
79
80 }  // namespace crypto