Coverage Report

Created: 2025-06-10 06:14

/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