1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// found in the LICENSE file. 4513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/symmetric_key.h" 6513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 74a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include <openssl/evp.h> 84a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include <openssl/rand.h> 94a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include <algorithm> 114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 12513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/logging.h" 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "base/string_util.h" 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/openssl_util.h" 16513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace crypto { 18513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 19513209b27ff55e2841eac0e4120199c23acce758Ben MurdochSymmetricKey::~SymmetricKey() { 204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch std::fill(key_.begin(), key_.end(), '\0'); // Zero out the confidential key. 21513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 22513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 23513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static 24513209b27ff55e2841eac0e4120199c23acce758Ben MurdochSymmetricKey* SymmetricKey::GenerateRandomKey(Algorithm algorithm, 25513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch size_t key_size_in_bits) { 264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch DCHECK_EQ(AES, algorithm); 274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch int key_size_in_bytes = key_size_in_bits / 8; 284a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch DCHECK_EQ(static_cast<int>(key_size_in_bits), key_size_in_bytes * 8); 294a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 304a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (key_size_in_bits == 0) 314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return NULL; 324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 33201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch OpenSSLErrStackTracer err_tracer(FROM_HERE); 344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch scoped_ptr<SymmetricKey> key(new SymmetricKey); 354a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch uint8* key_data = 364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch reinterpret_cast<uint8*>(WriteInto(&key->key_, key_size_in_bytes + 1)); 374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 38201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch int rv = RAND_bytes(key_data, key_size_in_bytes); 39201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return rv == 1 ? key.release() : NULL; 40513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 41513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 42513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static 43513209b27ff55e2841eac0e4120199c23acce758Ben MurdochSymmetricKey* SymmetricKey::DeriveKeyFromPassword(Algorithm algorithm, 44513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const std::string& password, 45513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const std::string& salt, 46513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch size_t iterations, 47513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch size_t key_size_in_bits) { 484a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch DCHECK(algorithm == AES || algorithm == HMAC_SHA1); 494a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch int key_size_in_bytes = key_size_in_bits / 8; 504a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch DCHECK_EQ(static_cast<int>(key_size_in_bits), key_size_in_bytes * 8); 514a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 52201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch OpenSSLErrStackTracer err_tracer(FROM_HERE); 534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch scoped_ptr<SymmetricKey> key(new SymmetricKey); 544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch uint8* key_data = 554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch reinterpret_cast<uint8*>(WriteInto(&key->key_, key_size_in_bytes + 1)); 56201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch int rv = PKCS5_PBKDF2_HMAC_SHA1(password.data(), password.length(), 57201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch reinterpret_cast<const uint8*>(salt.data()), 58201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch salt.length(), iterations, 59201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch key_size_in_bytes, key_data); 60201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return rv == 1 ? key.release() : NULL; 61513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 62513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 63513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// static 64513209b27ff55e2841eac0e4120199c23acce758Ben MurdochSymmetricKey* SymmetricKey::Import(Algorithm algorithm, 65513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch const std::string& raw_key) { 664a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch scoped_ptr<SymmetricKey> key(new SymmetricKey); 674a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch key->key_ = raw_key; 684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return key.release(); 69513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 70513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 71513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool SymmetricKey::GetRawKey(std::string* raw_key) { 724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch *raw_key = key_; 734a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return true; 74513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 75513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} // namespace crypto 77