• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/string_util.h"
15 #include "crypto/openssl_util.h"
16 
17 namespace crypto {
18 
~SymmetricKey()19 SymmetricKey::~SymmetricKey() {
20   std::fill(key_.begin(), key_.end(), '\0');  // Zero out the confidential key.
21 }
22 
23 // static
GenerateRandomKey(Algorithm algorithm,size_t key_size_in_bits)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);
29 
30   if (key_size_in_bits == 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, key_size_in_bytes);
39   return rv == 1 ? key.release() : NULL;
40 }
41 
42 // static
DeriveKeyFromPassword(Algorithm algorithm,const std::string & password,const std::string & salt,size_t iterations,size_t key_size_in_bits)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   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);
51 
52   OpenSSLErrStackTracer err_tracer(FROM_HERE);
53   scoped_ptr<SymmetricKey> key(new SymmetricKey);
54   uint8* key_data =
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;
61 }
62 
63 // static
Import(Algorithm algorithm,const std::string & raw_key)64 SymmetricKey* SymmetricKey::Import(Algorithm algorithm,
65                                    const std::string& raw_key) {
66   scoped_ptr<SymmetricKey> key(new SymmetricKey);
67   key->key_ = raw_key;
68   return key.release();
69 }
70 
GetRawKey(std::string * raw_key)71 bool SymmetricKey::GetRawKey(std::string* raw_key) {
72   *raw_key = key_;
73   return true;
74 }
75 
76 }  // namespace crypto
77