Botan 3.9.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
73 // NOLINTNEXTLINE(*-explicit-conversions) FIXME
74 [[nodiscard]] operator ESYS_TR() && noexcept;
75
76 private:
78
79 explicit SessionHandle(Session& session);
80
81 private:
82 std::optional<std::reference_wrapper<Session>> m_session;
83 SessionAttributes m_original_attributes;
84};
85
86} // namespace detail
87
89 public:
90 /**
91 * Instantiate an unauthenticated session that allows for the encryption
92 * of sensitive parameters passed to and from the TPM. The application's
93 * random salt is generated automatically (via the software RNG in the
94 * TSS2's crypto backend).
95 *
96 * Note that such a session is not protected against man-in-the-middle
97 * attacks with access to the data channel between the application and
98 * the TPM.
99 *
100 * @param ctx the TPM context
101 * @param sym_algo the symmetric algorithm used for parameter encryption
102 * @param hash_algo the hash algorithm in the HMAC used for authentication
103 */
104 static std::shared_ptr<Session> unauthenticated_session(const std::shared_ptr<Context>& ctx,
105 std::string_view sym_algo = "CFB(AES-256)",
106 std::string_view hash_algo = "SHA-256");
107
108 /**
109 * Instantiate a session based on a salt encrypted for @p tpm_key. This
110 * allows for the encryption of sensitive parameters passed to and from
111 * the TPM. The application's random salt is generated automatically (via
112 * the software RNG in the TSS2's crypto backend).
113 *
114 * Such a session is protected against man-in-the-middle attacks with
115 * access to the data channel between the application and the TPM, under
116 * the assumption that the @p tpm_key is not compromised.
117 *
118 * @param ctx the TPM context
119 * @param tpm_key the key to use for session establishment
120 * @param sym_algo the symmetric algorithm used for parameter encryption
121 * @param hash_algo the hash algorithm in the HMAC used for authentication
122 */
123 static std::shared_ptr<Session> authenticated_session(const std::shared_ptr<Context>& ctx,
124 const TPM2::PrivateKey& tpm_key,
125 std::string_view sym_algo = "CFB(AES-256)",
126 std::string_view hash_algo = "SHA-256");
127
128 public:
129 /**
130 * Create a session object from a user-provided transient handle.
131 *
132 * Use this to wrap an externally created session handle into a
133 * Botan::TPM2::Session instance to use it with the Botan::TPM2 library.
134 *
135 * Note that this will take ownership of the ESYS_TR handle and will
136 * release it when the object is destroyed.
137 *
138 * @param ctx the TPM context to use
139 * @param session_handle the transient handle to wrap
140 */
141 Session(std::shared_ptr<Context> ctx, ESYS_TR session_handle) : m_session(std::move(ctx), session_handle) {}
142
143 [[nodiscard]] detail::SessionHandle handle() { return detail::SessionHandle(*this); }
144
145 SessionAttributes attributes() const;
146 void set_attributes(SessionAttributes attributes);
147
148 secure_vector<uint8_t> tpm_nonce() const;
149
150 private:
152
154
155 ESYS_TR transient_handle() const noexcept { return m_session.transient_handle(); }
156
157 private:
158 Object m_session;
159};
160
161/**
162 * This bundles up to three sessions into a single object to be used in a
163 * single TSS2 library function call to simplify passing the sessions around
164 * internally.
165 */
167 public:
168 // NOLINTNEXTLINE(*-explicit-conversions) FIXME
169 SessionBundle(std::shared_ptr<Session> s1 = nullptr,
170 std::shared_ptr<Session> s2 = nullptr,
171 std::shared_ptr<Session> s3 = nullptr) :
172 m_sessions({std::move(s1), std::move(s2), std::move(s3)}) {}
173
174 [[nodiscard]] detail::SessionHandle operator[](size_t i) const noexcept {
175 if(m_sessions[i] == nullptr) {
176 return {};
177 } else {
178 return m_sessions[i]->handle();
179 }
180 }
181
182 private:
183 std::array<std::shared_ptr<Session>, 3> m_sessions;
184};
185
186} // namespace Botan::TPM2
187
188#endif
#define BOTAN_PUBLIC_API(maj, min)
Definition api.h:21
#define BOTAN_UNSTABLE_API
Definition api.h:34
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
static std::shared_ptr< Session > unauthenticated_session(const std::shared_ptr< Context > &ctx, std::string_view sym_algo="CFB(AES-256)", std::string_view hash_algo="SHA-256")
Session(std::shared_ptr< Context > ctx, ESYS_TR session_handle)
static std::shared_ptr< Session > authenticated_session(const std::shared_ptr< Context > &ctx, const TPM2::PrivateKey &tpm_key, std::string_view sym_algo="CFB(AES-256)", std::string_view hash_algo="SHA-256")
SessionAttributes attributes() const
detail::SessionHandle handle()
SessionHandle & operator=(SessionHandle &&)=delete
SessionHandle(SessionHandle &&)=delete
SessionHandle & operator=(const SessionHandle &)=delete
SessionHandle(const SessionHandle &)=delete
friend class Botan::TPM2::Session
uint8_t TPMA_SESSION
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:69
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.