Botan  2.7.0
Crypto and TLS for C++11
tpm.h
Go to the documentation of this file.
1 
2 /*
3 * TPM 1.2 interface
4 * (C) 2015 Jack Lloyd
5 *
6 * Botan is released under the Simplified BSD License (see license.txt)
7 */
8 
9 #ifndef BOTAN_TPM_H_
10 #define BOTAN_TPM_H_
11 
12 #include <botan/exceptn.h>
13 #include <botan/pk_keys.h>
14 #include <botan/bigint.h>
15 #include <botan/rng.h>
16 #include <botan/uuid.h>
17 #include <functional>
18 
19 //TODO remove this
20 #include <tss/tspi.h>
21 
22 namespace Botan {
23 
24 class BOTAN_PUBLIC_API(2,0) TPM_Error final : public Exception
25  {
26  public:
27  TPM_Error(const std::string& err) : Exception(err) {}
28  };
29 
30 /**
31 * Creates a connection to the TPM. All other TPM types take and hold
32 * a TPM_Context reference, so all other objects must be deallocated
33 * before ~TPM_Context runs.
34 *
35 * Use nullptr for the srk_password to indicate the well known secret
36 * (ie, an unencrypted SRK). This is usually what you want.
37 *
38 * TODO: handling owner password?
39 */
40 class BOTAN_PUBLIC_API(2,0) TPM_Context final
41  {
42  public:
43  /**
44  * User callback for getting the PIN. Will be passed the best available
45  * description of what we are attempting to load.
46  */
47  typedef std::function<std::string (std::string)> pin_cb;
48 
49  TPM_Context(pin_cb cb, const char* srk_password);
50 
51  ~TPM_Context();
52 
53  // Get data from the TPM's RNG, whatever that is
54  void gen_random(uint8_t out[], size_t out_len);
55 
56  // Uses Tspi_TPM_StirRandom to add data to TPM's internal pool
57  void stir_random(const uint8_t in[], size_t in_len);
58 
59  std::string get_user_pin(const std::string& who)
60  {
61  return m_pin_cb(who);
62  }
63 
64  uint32_t current_counter();
65 
66  TSS_HCONTEXT handle() const { return m_ctx; }
67  TSS_HKEY srk() const { return m_srk; }
68 
69  private:
70  std::function<std::string (std::string)> m_pin_cb;
71  TSS_HCONTEXT m_ctx;
72  TSS_HKEY m_srk;
73  TSS_HTPM m_tpm;
74  };
75 
76 class BOTAN_PUBLIC_API(2,0) TPM_RNG final : public Hardware_RNG
77  {
78  public:
79  TPM_RNG(TPM_Context& ctx) : m_ctx(ctx) {}
80 
81  void add_entropy(const uint8_t in[], size_t in_len) override
82  {
83  m_ctx.stir_random(in, in_len);
84  }
85 
86  void randomize(uint8_t out[], size_t out_len) override
87  {
88  m_ctx.gen_random(out, out_len);
89  }
90 
91  std::string name() const override { return "TPM_RNG"; }
92 
93  bool is_seeded() const override { return true; }
94 
95  private:
96  TPM_Context& m_ctx;
97 };
98 
99 enum class TPM_Storage_Type { User, System };
100 
101 /*
102 * Also implements the public interface, but does not have usable
103 * TODO: derive from RSA_PublicKey???
104 */
105 class BOTAN_PUBLIC_API(2,0) TPM_PrivateKey final : public Private_Key
106  {
107  public:
108  // TODO: key import?
109 
110  /*
111  * Create a new key on the TPM parented to the SRK
112  * @param bits must be 1024 or 2048
113  */
114  TPM_PrivateKey(TPM_Context& ctx, size_t bits, const char* key_password);
115 
116  // reference an existing TPM key using URL syntax from GnuTLS
117  // "tpmkey:uuid=79f07ca9-73ac-478a-9093-11ca6702e774;storage=user"
118  //TPM_PrivateKey(TPM_Context& ctx, const std::string& tpm_url);
119 
121  const std::string& uuid,
122  TPM_Storage_Type storage_type);
123 
125  const std::vector<uint8_t>& blob);
126 
127  /**
128  * If the key is not currently registered under a known UUID,
129  * generates a new random UUID and registers the key.
130  * Returns the access URL.
131  */
132  std::string register_key(TPM_Storage_Type storage_type);
133 
134  /**
135  * Returns a copy of the public key
136  */
137  std::unique_ptr<Public_Key> public_key() const;
138 
139  std::vector<uint8_t> export_blob() const;
140 
141  TPM_Context& ctx() const { return m_ctx; }
142 
143  TSS_HKEY handle() const { return m_key; }
144 
145  /*
146  * Returns the list of all keys (in URL format) registered with the system
147  */
148  static std::vector<std::string> registered_keys(TPM_Context& ctx);
149 
150  size_t estimated_strength() const override;
151 
152  size_t key_length() const override;
153 
154  AlgorithmIdentifier algorithm_identifier() const override;
155 
156  std::vector<uint8_t> public_key_bits() const override;
157 
158  secure_vector<uint8_t> private_key_bits() const override;
159 
160  bool check_key(RandomNumberGenerator& rng, bool) const override;
161 
162  std::string algo_name() const override { return "RSA"; } // ???
163 
164  std::unique_ptr<PK_Ops::Signature>
165  create_signature_op(RandomNumberGenerator& rng,
166  const std::string& params,
167  const std::string& provider) const override;
168 
169  private:
170  BigInt get_n() const;
171  BigInt get_e() const;
172 
173  TPM_Context& m_ctx;
174  TSS_HKEY m_key;
175 
176  // Only set for registered keys
177  UUID m_uuid;
178  TPM_Storage_Type m_storage;
179 
180  // Lazily computed in get_n, get_e
181  mutable BigInt m_n, m_e;
182  };
183 
184 // TODO: NVRAM interface
185 // TODO: PCR measurement, writing, key locking
186 
187 }
188 
189 #endif
TSS_HKEY handle() const
Definition: tpm.h:143
TPM_Storage_Type
Definition: tpm.h:99
bool is_seeded() const override
Definition: tpm.h:93
const BigInt & m_e
Definition: rsa.cpp:391
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:27
TSS_HKEY srk() const
Definition: tpm.h:67
TPM_Context & ctx() const
Definition: tpm.h:141
std::string name() const override
Definition: tpm.h:91
void randomize(uint8_t out[], size_t out_len) override
Definition: tpm.h:86
void add_entropy(const uint8_t in[], size_t in_len) override
Definition: tpm.h:81
std::string algo_name() const override
Definition: tpm.h:162
std::function< std::string(std::string)> pin_cb
Definition: tpm.h:47
Definition: alg_id.cpp:13
TPM_RNG(TPM_Context &ctx)
Definition: tpm.h:79
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88
std::string get_user_pin(const std::string &who)
Definition: tpm.h:59
TPM_Error(const std::string &err)
Definition: tpm.h:27
TSS_HCONTEXT handle() const
Definition: tpm.h:66
const RSA_PrivateKey & m_key
Definition: rsa.cpp:277
const BigInt & m_n
Definition: rsa.cpp:390