/src/botan/build/include/public/botan/tls_algos.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * (C) 2017 Jack Lloyd |
3 | | * |
4 | | * Botan is released under the Simplified BSD License (see license.txt) |
5 | | */ |
6 | | |
7 | | #ifndef BOTAN_TLS_ALGO_IDS_H_ |
8 | | #define BOTAN_TLS_ALGO_IDS_H_ |
9 | | |
10 | | #include <botan/asn1_obj.h> |
11 | | #include <botan/pk_keys.h> |
12 | | #include <botan/types.h> |
13 | | #include <optional> |
14 | | #include <string> |
15 | | #include <vector> |
16 | | |
17 | | //BOTAN_FUTURE_INTERNAL_HEADER(tls_algos.h) |
18 | | |
19 | | namespace Botan::TLS { |
20 | | |
21 | | enum class Cipher_Algo { |
22 | | CHACHA20_POLY1305, |
23 | | |
24 | | AES_128_GCM, |
25 | | AES_256_GCM, |
26 | | |
27 | | AES_256_OCB, |
28 | | |
29 | | CAMELLIA_128_GCM, |
30 | | CAMELLIA_256_GCM, |
31 | | |
32 | | ARIA_128_GCM, |
33 | | ARIA_256_GCM, |
34 | | |
35 | | AES_128_CCM, |
36 | | AES_256_CCM, |
37 | | AES_128_CCM_8, |
38 | | AES_256_CCM_8, |
39 | | |
40 | | AES_128_CBC_HMAC_SHA1, |
41 | | AES_128_CBC_HMAC_SHA256, |
42 | | AES_256_CBC_HMAC_SHA1, |
43 | | AES_256_CBC_HMAC_SHA256, |
44 | | AES_256_CBC_HMAC_SHA384, |
45 | | |
46 | | DES_EDE_CBC_HMAC_SHA1, |
47 | | }; |
48 | | |
49 | | enum class KDF_Algo { |
50 | | SHA_1, |
51 | | SHA_256, |
52 | | SHA_384, |
53 | | }; |
54 | | |
55 | | std::string BOTAN_DLL kdf_algo_to_string(KDF_Algo algo); |
56 | | |
57 | | enum class Nonce_Format { |
58 | | CBC_MODE, |
59 | | AEAD_IMPLICIT_4, |
60 | | AEAD_XOR_12, |
61 | | NULL_CIPHER, |
62 | | }; |
63 | | |
64 | | // TODO encoding should match signature_algorithms extension |
65 | | // TODO this should include hash etc as in TLS v1.3 |
66 | | enum class Auth_Method { |
67 | | RSA, |
68 | | ECDSA, |
69 | | |
70 | | // To support TLS 1.3 ciphersuites, which do not determine the auth method |
71 | | UNDEFINED, |
72 | | |
73 | | // These are placed outside the encodable range |
74 | | IMPLICIT = 0x10000 |
75 | | }; |
76 | | |
77 | | std::string BOTAN_TEST_API auth_method_to_string(Auth_Method method); |
78 | | Auth_Method BOTAN_TEST_API auth_method_from_string(std::string_view str); |
79 | | |
80 | | /* |
81 | | * Matches with wire encoding |
82 | | */ |
83 | | enum class Group_Params_Code : uint16_t { |
84 | | NONE = 0, |
85 | | |
86 | | SECP256R1 = 23, |
87 | | SECP384R1 = 24, |
88 | | SECP521R1 = 25, |
89 | | BRAINPOOL256R1 = 26, |
90 | | BRAINPOOL384R1 = 27, |
91 | | BRAINPOOL512R1 = 28, |
92 | | |
93 | | X25519 = 29, |
94 | | X448 = 30, |
95 | | |
96 | | FFDHE_2048 = 256, |
97 | | FFDHE_3072 = 257, |
98 | | FFDHE_4096 = 258, |
99 | | FFDHE_6144 = 259, |
100 | | FFDHE_8192 = 260, |
101 | | |
102 | | // https://datatracker.ietf.org/doc/draft-connolly-tls-mlkem-key-agreement/05/ |
103 | | ML_KEM_512 = 0x0200, |
104 | | ML_KEM_768 = 0x0201, |
105 | | ML_KEM_1024 = 0x0202, |
106 | | |
107 | | // libOQS defines those in: |
108 | | // https://github.com/open-quantum-safe/oqs-provider/blob/main/ALGORITHMS.md |
109 | | // (last update: 6th June 2025 - matching oqs commit 9447f68) |
110 | | eFRODOKEM_640_SHAKE_OQS = 0xFE03, |
111 | | eFRODOKEM_976_SHAKE_OQS = 0xFE09, |
112 | | eFRODOKEM_1344_SHAKE_OQS = 0xFE0E, |
113 | | eFRODOKEM_640_AES_OQS = 0xFE00, |
114 | | eFRODOKEM_976_AES_OQS = 0xFE06, |
115 | | eFRODOKEM_1344_AES_OQS = 0xFE0C, |
116 | | |
117 | | // https://datatracker.ietf.org/doc/draft-kwiatkowski-tls-ecdhe-mlkem/03/ |
118 | | HYBRID_SECP256R1_ML_KEM_768 = 0x11EB, |
119 | | HYBRID_SECP384R1_ML_KEM_1024 = 0x11ED, |
120 | | HYBRID_X25519_ML_KEM_768 = 0x11EC, |
121 | | |
122 | | // https://github.com/open-quantum-safe/oqs-provider/blob/main/ALGORITHMS.md |
123 | | // (last update: 6th June 2025 - matching oqs commit 9447f68) |
124 | | HYBRID_X25519_eFRODOKEM_640_SHAKE_OQS = 0xFE05, |
125 | | HYBRID_X25519_eFRODOKEM_640_AES_OQS = 0xFE02, |
126 | | |
127 | | HYBRID_X448_eFRODOKEM_976_SHAKE_OQS = 0xFE0B, |
128 | | HYBRID_X448_eFRODOKEM_976_AES_OQS = 0xFE08, |
129 | | |
130 | | HYBRID_SECP256R1_eFRODOKEM_640_SHAKE_OQS = 0xFE04, |
131 | | HYBRID_SECP256R1_eFRODOKEM_640_AES_OQS = 0xFE01, |
132 | | |
133 | | HYBRID_SECP384R1_eFRODOKEM_976_SHAKE_OQS = 0xFE0A, |
134 | | HYBRID_SECP384R1_eFRODOKEM_976_AES_OQS = 0xFE07, |
135 | | |
136 | | HYBRID_SECP521R1_eFRODOKEM_1344_SHAKE_OQS = 0xFE0F, |
137 | | HYBRID_SECP521R1_eFRODOKEM_1344_AES_OQS = 0xFE0D, |
138 | | }; |
139 | | |
140 | | class BOTAN_PUBLIC_API(3, 2) Group_Params final { |
141 | | public: |
142 | | using enum Group_Params_Code; |
143 | | |
144 | 5.56k | constexpr Group_Params() : m_code(Group_Params_Code::NONE) {} |
145 | | |
146 | 25.1k | constexpr Group_Params(Group_Params_Code code) : m_code(code) {} |
147 | | |
148 | 100k | constexpr Group_Params(uint16_t code) : m_code(static_cast<Group_Params_Code>(code)) {} |
149 | | |
150 | | /** |
151 | | * @returns std::nullopt if an unknown name |
152 | | */ |
153 | | static std::optional<Group_Params> from_string(std::string_view group_name); |
154 | | |
155 | 102k | constexpr bool operator==(Group_Params_Code code) const { return m_code == code; } |
156 | | |
157 | 1.73M | constexpr bool operator==(Group_Params other) const { return m_code == other.m_code; } |
158 | | |
159 | 0 | constexpr bool operator<(Group_Params other) const { return m_code < other.m_code; } |
160 | | |
161 | 0 | constexpr Group_Params_Code code() const { return m_code; } |
162 | | |
163 | 302k | constexpr uint16_t wire_code() const { return static_cast<uint16_t>(m_code); } |
164 | | |
165 | | /** |
166 | | * Returns false if this group/KEX is not available in the build configuration |
167 | | */ |
168 | | bool is_available() const; |
169 | | |
170 | 177k | constexpr bool is_x25519() const { return m_code == Group_Params_Code::X25519; } |
171 | | |
172 | 172k | constexpr bool is_x448() const { return m_code == Group_Params_Code::X448; } |
173 | | |
174 | 186k | constexpr bool is_ecdh_named_curve() const { |
175 | 186k | return m_code == Group_Params_Code::SECP256R1 || m_code == Group_Params_Code::SECP384R1 || |
176 | 186k | m_code == Group_Params_Code::SECP521R1 || m_code == Group_Params_Code::BRAINPOOL256R1 || |
177 | 186k | m_code == Group_Params_Code::BRAINPOOL384R1 || m_code == Group_Params_Code::BRAINPOOL512R1; |
178 | 186k | } |
179 | | |
180 | 145k | constexpr bool is_in_ffdhe_range() const { |
181 | | // See RFC 7919 |
182 | 145k | return wire_code() >= 256 && wire_code() < 512; |
183 | 145k | } |
184 | | |
185 | 22.4k | constexpr bool is_dh_named_group() const { |
186 | 22.4k | return m_code == Group_Params_Code::FFDHE_2048 || m_code == Group_Params_Code::FFDHE_3072 || |
187 | 22.4k | m_code == Group_Params_Code::FFDHE_4096 || m_code == Group_Params_Code::FFDHE_6144 || |
188 | 22.4k | m_code == Group_Params_Code::FFDHE_8192; |
189 | 22.4k | } |
190 | | |
191 | 91.3k | constexpr bool is_pure_ml_kem() const { |
192 | 91.3k | return m_code == Group_Params_Code::ML_KEM_512 || m_code == Group_Params_Code::ML_KEM_768 || |
193 | 91.3k | m_code == Group_Params_Code::ML_KEM_1024; |
194 | 91.3k | } |
195 | | |
196 | 91.3k | constexpr bool is_pure_frodokem() const { |
197 | 91.3k | return m_code == Group_Params_Code::eFRODOKEM_640_SHAKE_OQS || |
198 | 91.3k | m_code == Group_Params_Code::eFRODOKEM_976_SHAKE_OQS || |
199 | 91.3k | m_code == Group_Params_Code::eFRODOKEM_1344_SHAKE_OQS || |
200 | 91.3k | m_code == Group_Params_Code::eFRODOKEM_640_AES_OQS || |
201 | 91.3k | m_code == Group_Params_Code::eFRODOKEM_976_AES_OQS || |
202 | 91.3k | m_code == Group_Params_Code::eFRODOKEM_1344_AES_OQS; |
203 | 91.3k | } |
204 | | |
205 | 174k | constexpr bool is_pure_ecc_group() const { return is_x25519() || is_x448() || is_ecdh_named_curve(); } |
206 | | |
207 | 91.3k | constexpr bool is_post_quantum() const { |
208 | 91.3k | BOTAN_DIAGNOSTIC_PUSH |
209 | 91.3k | BOTAN_DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS |
210 | | |
211 | 91.3k | return is_pure_ml_kem() || is_pure_frodokem() || is_pqc_hybrid(); |
212 | | |
213 | 91.3k | BOTAN_DIAGNOSTIC_POP |
214 | 91.3k | } |
215 | | |
216 | 91.3k | constexpr bool is_pqc_hybrid_ml_kem() const { |
217 | 91.3k | return m_code == Group_Params_Code::HYBRID_SECP256R1_ML_KEM_768 || |
218 | 91.3k | m_code == Group_Params_Code::HYBRID_SECP384R1_ML_KEM_1024 || |
219 | 91.3k | m_code == Group_Params_Code::HYBRID_X25519_ML_KEM_768; |
220 | 91.3k | } |
221 | | |
222 | 80.9k | constexpr bool is_pqc_hybrid_frodokem() const { |
223 | 80.9k | return m_code == Group_Params_Code::HYBRID_X25519_eFRODOKEM_640_SHAKE_OQS || |
224 | 80.9k | m_code == Group_Params_Code::HYBRID_X25519_eFRODOKEM_640_AES_OQS || |
225 | 80.9k | m_code == Group_Params_Code::HYBRID_X448_eFRODOKEM_976_SHAKE_OQS || |
226 | 80.9k | m_code == Group_Params_Code::HYBRID_X448_eFRODOKEM_976_AES_OQS || |
227 | 80.9k | m_code == Group_Params_Code::HYBRID_SECP256R1_eFRODOKEM_640_SHAKE_OQS || |
228 | 80.9k | m_code == Group_Params_Code::HYBRID_SECP256R1_eFRODOKEM_640_AES_OQS || |
229 | 80.9k | m_code == Group_Params_Code::HYBRID_SECP384R1_eFRODOKEM_976_SHAKE_OQS || |
230 | 80.9k | m_code == Group_Params_Code::HYBRID_SECP384R1_eFRODOKEM_976_AES_OQS || |
231 | 80.9k | m_code == Group_Params_Code::HYBRID_SECP521R1_eFRODOKEM_1344_SHAKE_OQS || |
232 | 80.9k | m_code == Group_Params_Code::HYBRID_SECP521R1_eFRODOKEM_1344_AES_OQS; |
233 | 80.9k | } |
234 | | |
235 | 91.3k | constexpr bool is_pqc_hybrid() const { return is_pqc_hybrid_ml_kem() || is_pqc_hybrid_frodokem(); } |
236 | | |
237 | 0 | constexpr bool is_kem() const { |
238 | 0 | BOTAN_DIAGNOSTIC_PUSH |
239 | 0 | BOTAN_DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS |
240 | |
|
241 | 0 | return is_pure_ml_kem() || is_pure_frodokem() || is_pqc_hybrid(); |
242 | |
|
243 | 0 | BOTAN_DIAGNOSTIC_POP |
244 | 0 | } |
245 | | |
246 | | // If this is a pqc hybrid group, returns the ECC ID |
247 | | std::optional<Group_Params_Code> pqc_hybrid_ecc() const; |
248 | | |
249 | | // Returns std::nullopt if the param has no known name |
250 | | std::optional<std::string> to_string() const; |
251 | | |
252 | | private: |
253 | | Group_Params_Code m_code; |
254 | | }; |
255 | | |
256 | | enum class Kex_Algo { |
257 | | STATIC_RSA, |
258 | | DH, |
259 | | ECDH, |
260 | | PSK, |
261 | | ECDHE_PSK, |
262 | | DHE_PSK, |
263 | | KEM, |
264 | | KEM_PSK, |
265 | | HYBRID, |
266 | | HYBRID_PSK, |
267 | | |
268 | | // To support TLS 1.3 ciphersuites, which do not determine the kex algo |
269 | | UNDEFINED |
270 | | }; |
271 | | |
272 | | std::string BOTAN_TEST_API kex_method_to_string(Kex_Algo method); |
273 | | Kex_Algo BOTAN_TEST_API kex_method_from_string(std::string_view str); |
274 | | |
275 | 10.0k | inline bool key_exchange_is_psk(Kex_Algo m) { |
276 | 10.0k | return (m == Kex_Algo::PSK || m == Kex_Algo::ECDHE_PSK || m == Kex_Algo::DHE_PSK); |
277 | 10.0k | } |
278 | | |
279 | | } // namespace Botan::TLS |
280 | | |
281 | | #endif |