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