Botan 3.6.0
Crypto and TLS for C&
tpm2_session.h
Go to the documentation of this file.
1/*
2* TPM 2 Auth Session Wrapper
3* (C) 2024 Jack Lloyd
4* (C) 2024 René Meusel, Amos Treiber - Rohde & Schwarz Cybersecurity GmbH, financed by LANCOM Systems GmbH
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8#ifndef BOTAN_TPM2_SESSION_H_
9#define BOTAN_TPM2_SESSION_H_
10
11#include <botan/secmem.h>
12#include <botan/tpm2_context.h>
13#include <botan/tpm2_object.h>
14
15#include <array>
16#include <memory>
17
18namespace Botan::TPM2 {
19
20using TPMA_SESSION = uint8_t;
21
22/**
23 * See TPM 2.0 Part 2, Section 8.4
24 */
25
27 static SessionAttributes read(TPMA_SESSION attributes);
28 static TPMA_SESSION render(SessionAttributes attributes);
29
30 /// The session may or may not remain active after the successful completion of any command.
31 bool continue_session = false;
32
33 /// Indicates that a command should only be executed if the session is exclusive.
34 bool audit_exclusive = false;
35
36 /// Indicates that the audit digest should be initialized and exclusive status of the session SET
37 bool audit_reset = false;
38
39 /// Indicates that the first parameter of the command is to be decrypted by the TPM
40 bool decrypt = false;
41
42 /// Indicates that the first parameter of a command's response is to be encrypted by the TPM
43 bool encrypt = false;
44
45 /// Indicates that the session is fused for audit and that audit_exclusive and audit_reset have meaning
46 bool audit = false;
47};
48
49class Session;
50class PrivateKey;
51
52namespace detail {
53
54/**
55 * This wraps a Session object and ensures that the session's attributes are
56 * restored to their original state after they have been modified by a (failing)
57 * TSS2 library function.
58 *
59 * This is a workaround for the fact that TSS2 library calls may modify the
60 * session's attributes and not reset them when the call fails.
61 */
63 public:
64 SessionHandle() = default;
65
66 SessionHandle(const SessionHandle&) = delete;
70
72 [[nodiscard]] operator ESYS_TR() && noexcept;
73
74 private:
76
77 SessionHandle(Session& session);
78
79 private:
80 std::optional<std::reference_wrapper<Session>> m_session;
81 SessionAttributes m_original_attributes;
82};
83
84} // namespace detail
85
87 public:
88 /**
89 * Instantiate an unauthenticated session that allows for the encryption
90 * of sensitive parameters passed to and from the TPM. The application's
91 * random salt is generated automatically (via the software RNG in the
92 * TSS2's crypto backend).
93 *
94 * Note that such a session is not protected against man-in-the-middle
95 * attacks with access to the data channel between the application and
96 * the TPM.
97 *
98 * @param ctx the TPM context
99 * @param sym_algo the symmetric algorithm used for parameter encryption
100 * @param hash_algo the hash algorithm in the HMAC used for authentication
101 */
102 static std::shared_ptr<Session> unauthenticated_session(const std::shared_ptr<Context>& ctx,
103 std::string_view sym_algo = "CFB(AES-256)",
104 std::string_view hash_algo = "SHA-256");
105
106 /**
107 * Instantiate a session based on a salt encrypted for @p tpm_key. This
108 * allows for the encryption of sensitive parameters passed to and from
109 * the TPM. The application's random salt is generated automatically (via
110 * the software RNG in the TSS2's crypto backend).
111 *
112 * Such a session is protected against man-in-the-middle attacks with
113 * access to the data channel between the application and the TPM, under
114 * the assumption that the @p tpm_key is not compromised.
115 *
116 * @param ctx the TPM context
117 * @param tpm_key the key to use for session establishment
118 * @param sym_algo the symmetric algorithm used for parameter encryption
119 * @param hash_algo the hash algorithm in the HMAC used for authentication
120 */
121 static std::shared_ptr<Session> authenticated_session(const std::shared_ptr<Context>& ctx,
122 const TPM2::PrivateKey& tpm_key,
123 std::string_view sym_algo = "CFB(AES-256)",
124 std::string_view hash_algo = "SHA-256");
125
126 public:
127 /**
128 * Create a session object from a user-provided transient handle.
129 *
130 * Use this to wrap an externally created session handle into a
131 * Botan::TPM2::Session instance to use it with the Botan::TPM2 library.
132 *
133 * Note that this will take ownership of the ESYS_TR handle and will
134 * release it when the object is destroyed.
135 *
136 * @param ctx the TPM context to use
137 * @param session_handle the transient handle to wrap
138 */
139 Session(std::shared_ptr<Context> ctx, ESYS_TR session_handle) : m_session(std::move(ctx), session_handle) {}
140
141 [[nodiscard]] detail::SessionHandle handle() { return *this; }
142
143 SessionAttributes attributes() const;
144 void set_attributes(SessionAttributes attributes);
145
146 secure_vector<uint8_t> tpm_nonce() const;
147
148 private:
150
151 Session(Object session, SessionAttributes attributes);
152
153 ESYS_TR transient_handle() const noexcept { return m_session.transient_handle(); }
154
155 private:
156 Object m_session;
157};
158
160 if(m_session) {
161 m_session->get().set_attributes(m_original_attributes);
162 }
163}
164
166 m_session(session), m_original_attributes(session.attributes()) {}
167
168/**
169 * This bundles up to three sessions into a single object to be used in a
170 * single TSS2 library function call to simplify passing the sessions around
171 * internally.
172 */
174 public:
175 SessionBundle(std::shared_ptr<Session> s1 = nullptr,
176 std::shared_ptr<Session> s2 = nullptr,
177 std::shared_ptr<Session> s3 = nullptr) :
178 m_sessions({std::move(s1), std::move(s2), std::move(s3)}) {}
179
180 [[nodiscard]] detail::SessionHandle operator[](size_t i) const noexcept {
181 if(m_sessions[i] == nullptr) {
182 return {};
183 } else {
184 return m_sessions[i]->handle();
185 }
186 }
187
188 private:
189 std::array<std::shared_ptr<Session>, 3> m_sessions;
190};
191
192} // namespace Botan::TPM2
193
194#endif
SessionBundle(std::shared_ptr< Session > s1=nullptr, std::shared_ptr< Session > s2=nullptr, std::shared_ptr< Session > s3=nullptr)
detail::SessionHandle operator[](size_t i) const noexcept
Session(std::shared_ptr< Context > ctx, ESYS_TR session_handle)
detail::SessionHandle handle()
SessionHandle & operator=(SessionHandle &&)=delete
SessionHandle(SessionHandle &&)=delete
SessionHandle & operator=(const SessionHandle &)=delete
SessionHandle(const SessionHandle &)=delete
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition compiler.h:31
#define BOTAN_UNSTABLE_API
Definition compiler.h:44
uint8_t TPMA_SESSION
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:61
static SessionAttributes read(TPMA_SESSION attributes)
bool audit_exclusive
Indicates that a command should only be executed if the session is exclusive.
bool decrypt
Indicates that the first parameter of the command is to be decrypted by the TPM.
bool continue_session
The session may or may not remain active after the successful completion of any command.
bool encrypt
Indicates that the first parameter of a command's response is to be encrypted by the TPM.
bool audit_reset
Indicates that the audit digest should be initialized and exclusive status of the session SET.
static TPMA_SESSION render(SessionAttributes attributes)
bool audit
Indicates that the session is fused for audit and that audit_exclusive and audit_reset have meaning.
uint32_t ESYS_TR
Forward declaration of TSS2 type for convenience.