1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#ifndef CRYPTO_SYMMETRIC_KEY_H_
6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define CRYPTO_SYMMETRIC_KEY_H_
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(USE_NSS)
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/scoped_nss_types.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_MACOSX)
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <Security/cssmtype.h>
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_WIN)
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/scoped_capi_types.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace crypto {
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Wraps a platform-specific symmetric key and allows it to be held in a
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// scoped_ptr.
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SymmetricKey {
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Defines the algorithm that a key will be used with. See also
284a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // classs Encrptor.
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  enum Algorithm {
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AES,
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HMAC_SHA1,
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~SymmetricKey();
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Generates a random key suitable to be used with |algorithm| and of
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // |key_size_in_bits| bits.
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The caller is responsible for deleting the returned SymmetricKey.
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static SymmetricKey* GenerateRandomKey(Algorithm algorithm,
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         size_t key_size_in_bits);
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
424a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // Derives a key from the supplied password and salt using PBKDF2, suitable
434a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // for use with specified |algorithm|. Note |algorithm| is not the algorithm
444a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // used to derive the key from the password. The caller is responsible for
454a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // deleting the returned SymmetricKey.
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static SymmetricKey* DeriveKeyFromPassword(Algorithm algorithm,
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             const std::string& password,
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             const std::string& salt,
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             size_t iterations,
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             size_t key_size_in_bits);
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
52201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Imports an array of key bytes in |raw_key|. This key may have been
53201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // generated by GenerateRandomKey or DeriveKeyFromPassword and exported with
54201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // GetRawKey, or via another compatible method. The key must be of suitable
55201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // size for use with |algorithm|. The caller owns the returned SymmetricKey.
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static SymmetricKey* Import(Algorithm algorithm, const std::string& raw_key);
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#if defined(USE_OPENSSL)
594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  const std::string& key() { return key_; }
604a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#elif defined(USE_NSS)
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PK11SymKey* key() const { return key_.get(); }
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_MACOSX)
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CSSM_DATA cssm_data() const;
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_WIN)
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HCRYPTKEY key() const { return key_.get(); }
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Extracts the raw key from the platform specific data.
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Warning: |raw_key| holds the raw key as bytes and thus must be handled
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // carefully.
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool GetRawKey(std::string* raw_key);
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
74513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#if defined(USE_OPENSSL)
754a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  SymmetricKey() {}
764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  std::string key_;
77513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#elif defined(USE_NSS)
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  explicit SymmetricKey(PK11SymKey* key);
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScopedPK11SymKey key_;
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_MACOSX)
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SymmetricKey(const void* key_data, size_t key_size_in_bits);
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string key_;
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#elif defined(OS_WIN)
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SymmetricKey(HCRYPTPROV provider, HCRYPTKEY key,
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch               const void* key_data, size_t key_size_in_bytes);
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScopedHCRYPTPROV provider_;
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScopedHCRYPTKEY key_;
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Contains the raw key, if it is known during initialization and when it
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // is likely that the associated |provider_| will be unable to export the
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // |key_|. This is the case of HMAC keys when the key size exceeds 16 bytes
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // when using the default RSA provider.
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(rsleevi): See if KP_EFFECTIVE_KEYLEN is the reason why CryptExportKey
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // fails with NTE_BAD_KEY/NTE_BAD_LEN
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string raw_key_;
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(SymmetricKey);
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}  // namespace crypto
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif  // CRYPTO_SYMMETRIC_KEY_H_
105