quic.h (10860B)
1 /* quic.h 2 * 3 * Copyright (C) 2006-2025 wolfSSL Inc. 4 * 5 * This file is part of wolfSSL. 6 * 7 * wolfSSL is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * wolfSSL is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA 20 */ 21 22 23 24 /* wolfSSL QUIC API */ 25 26 #ifndef WOLFSSL_QUIC_H 27 #define WOLFSSL_QUIC_H 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 #ifdef WOLFSSL_QUIC 34 35 #include <stdint.h> 36 37 /* QUIC operates on three encryption levels which determine 38 * which keys/algos are used for de-/encryption. These are 39 * kept separately for incoming and outgoing data and. 40 * Due to the nature of UDP, more than one might be in use 41 * at the same time due to resends or out-of-order arrivals. 42 */ 43 typedef enum wolfssl_encryption_level_t { 44 wolfssl_encryption_initial = 0, 45 wolfssl_encryption_early_data, 46 wolfssl_encryption_handshake, 47 wolfssl_encryption_application 48 } WOLFSSL_ENCRYPTION_LEVEL; 49 50 51 /* All QUIC related callbacks to the application. 52 */ 53 typedef struct wolfssl_quic_method_t WOLFSSL_QUIC_METHOD; 54 55 struct wolfssl_quic_method_t { 56 /** 57 * Provide secrets to the QUIC stack when they become available in the SSL 58 * instance during handshake processing. read/write secrets have the same 59 * length. A call may only provide one, passing NULL as the other. 60 */ 61 int (*set_encryption_secrets)(WOLFSSL* ssl, WOLFSSL_ENCRYPTION_LEVEL level, 62 const uint8_t* read_secret, 63 const uint8_t* write_secret, 64 size_t secret_len); 65 /** 66 * Provide handshake packets to the QUIC stack to send to the peer. The 67 * QUIC stack will wrap these and take care of re-transmissions. 68 */ 69 int (*add_handshake_data)(WOLFSSL* ssl, WOLFSSL_ENCRYPTION_LEVEL level, 70 const uint8_t* data, size_t len); 71 /** 72 * Flush any buffered packets during handshake. 73 */ 74 int (*flush_flight)(WOLFSSL* ssl); 75 /** 76 * Send a TLS alert that happened during handshake. In QUIC, such alerts 77 * lead to connection shutdown. 78 */ 79 int (*send_alert)(WOLFSSL* ssl, WOLFSSL_ENCRYPTION_LEVEL level, 80 uint8_t alert); 81 }; 82 83 84 /** 85 * Mark the given SSL context for QUIC protocol handling. Meaning all 86 * SSL instances derived from it will inherit this. Provides all callbacks 87 * to the QUIC application the SSL stack needs. 88 */ 89 WOLFSSL_API 90 int wolfSSL_CTX_set_quic_method(WOLFSSL_CTX* ctx, 91 const WOLFSSL_QUIC_METHOD* quic_method); 92 /** 93 * Mark exactly this SSL instance for QUIC protocol handling. 94 * Provides all callbacks to the QUIC application the SSL stack needs. 95 */ 96 WOLFSSL_API 97 int wolfSSL_set_quic_method(WOLFSSL* ssl, 98 const WOLFSSL_QUIC_METHOD* quic_method); 99 100 /** 101 * Check if QUIC handling has been installed on the given SSL instance. 102 */ 103 WOLFSSL_API int wolfSSL_is_quic(WOLFSSL* ssl); 104 105 /** 106 * Return the current encryption level of the SSL instance for READs. 107 */ 108 WOLFSSL_API 109 WOLFSSL_ENCRYPTION_LEVEL wolfSSL_quic_read_level(const WOLFSSL* ssl); 110 111 /** 112 * Return the current encryption level of the SSL instance for WRITEs. 113 */ 114 WOLFSSL_API 115 WOLFSSL_ENCRYPTION_LEVEL wolfSSL_quic_write_level(const WOLFSSL* ssl); 116 117 118 /** 119 * Configure the QUIC transport version to use. On `use_legacy` != 0, 120 * selects TLSX_KEY_QUIC_TP_PARAMS_DRAFT, otherwise TLSX_KEY_QUIC_TP_PARAMS. 121 * This method is part of the BoringSSL API and replicated here for app 122 * portability (as in quictls/openssl). 123 */ 124 WOLFSSL_API 125 void wolfSSL_set_quic_use_legacy_codepoint(WOLFSSL* ssl, int use_legacy); 126 127 /** 128 * Set the TLS extension for the transport parameter version to announce 129 * to the peer. Known values are TLSX_KEY_QUIC_TP_PARAMS (V1) and 130 * TLSX_KEY_QUIC_TP_PARAMS_DRAFT. 131 * Setting it to 0 will announce both V1 and draft versions to a server. 132 * Servers will, on 0, select the latest version seen from the client. 133 * Default is 0. 134 */ 135 WOLFSSL_API 136 void wolfSSL_set_quic_transport_version(WOLFSSL* ssl, int version); 137 138 /** 139 * Get the configured transport version. 140 */ 141 WOLFSSL_API int wolfSSL_get_quic_transport_version(const WOLFSSL* ssl); 142 143 /** 144 * Set the raw QUIC transport parameter that will be sent in the TLS extension 145 * to the peer, using the configured transport version(s). 146 */ 147 WOLFSSL_API int wolfSSL_set_quic_transport_params(WOLFSSL* ssl, 148 const uint8_t* params, 149 size_t params_len); 150 /** 151 * Get the raw QUIC transport parameter as retrieved via TLS Extension 152 * from the peer. If the peer announced several versions, 153 * return the latest one. 154 * If the extension has not arrived yet, initializes out parameter to 155 * NULL, resp. 0. 156 */ 157 WOLFSSL_API 158 void wolfSSL_get_peer_quic_transport_params(const WOLFSSL* ssl, 159 const uint8_t* *out_params, 160 size_t* out_params_len); 161 162 /** 163 * Get the QUIC version negotiated with the peer during the handshake. 164 */ 165 WOLFSSL_API int wolfSSL_get_peer_quic_transport_version(const WOLFSSL* ssl); 166 167 #ifdef WOLFSSL_EARLY_DATA 168 WOLFSSL_API void wolfSSL_set_quic_early_data_enabled(WOLFSSL* ssl, int enabled); 169 #endif 170 171 /** 172 * Advisory amount of the maximum data a QUIC protocol handler should have 173 * in flight. This varies during handshake processing, for example certificate 174 * exchange will increase the limit. 175 */ 176 WOLFSSL_API 177 size_t wolfSSL_quic_max_handshake_flight_len(const WOLFSSL* ssl, 178 WOLFSSL_ENCRYPTION_LEVEL level); 179 180 181 /** 182 * The QUIC protocol handler provides peer TLS records to the SSL instance 183 * during handshake to progress it. The SSL instance will use the registered 184 * callbacks to send packets to the peer. 185 * Encryption level is provided to indicate how to decrypt the data. Data may 186 * be added for levels not yet reached by the SSL instance. However, data 187 * may only be added in ever increasing levels and levels may only increase 188 * at TLS record boundaries. Any violation will make this function fail. 189 */ 190 WOLFSSL_API 191 int wolfSSL_provide_quic_data(WOLFSSL* ssl, WOLFSSL_ENCRYPTION_LEVEL level, 192 const uint8_t* data, size_t len); 193 194 WOLFSSL_API 195 int wolfSSL_quic_do_handshake(WOLFSSL* ssl); 196 197 /** 198 * Process any CRYPTO data added post-handshake. 199 */ 200 WOLFSSL_API int wolfSSL_process_quic_post_handshake(WOLFSSL* ssl); 201 202 /** 203 * Process any pending input and flush all output. Can be invoked 204 * during and/or after handshake processing. 205 */ 206 WOLFSSL_API int wolfSSL_quic_read_write(WOLFSSL* ssl); 207 208 /** 209 * Get the AEAD cipher that is currently selected in the SSL instance. 210 * Will return NULL if none has been selected so far. This is used by the 211 * QUIC stack to encrypt/decrypt packets after the handshake. 212 */ 213 WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_quic_get_aead(WOLFSSL* ssl); 214 215 /** 216 * Use to classify the AEAD cipher for key reuse limits. 217 */ 218 WOLFSSL_API int wolfSSL_quic_aead_is_gcm(const WOLFSSL_EVP_CIPHER* aead_cipher); 219 WOLFSSL_API int wolfSSL_quic_aead_is_ccm(const WOLFSSL_EVP_CIPHER* aead_cipher); 220 WOLFSSL_API 221 int wolfSSL_quic_aead_is_chacha20(const WOLFSSL_EVP_CIPHER* aead_cipher); 222 223 /** 224 * Get the 'tag' length used by the AEAD cipher. Encryption buffer lengths 225 * are plaintext length plus this tag length. 226 */ 227 WOLFSSL_API 228 size_t wolfSSL_quic_get_aead_tag_len(const WOLFSSL_EVP_CIPHER* aead_cipher); 229 230 /** 231 * The message digest currently selected in the SSL instance. 232 */ 233 WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_quic_get_md(WOLFSSL* ssl); 234 235 /** 236 * The QUIC header protection cipher matching the AEAD cipher currently 237 * selected in the SSL instance. 238 */ 239 WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_quic_get_hp(WOLFSSL* ssl); 240 241 /** 242 * Create and initialize a cipher context for use in en- or decryption. 243 */ 244 WOLFSSL_API WOLFSSL_EVP_CIPHER_CTX* 245 wolfSSL_quic_crypt_new(const WOLFSSL_EVP_CIPHER* cipher, 246 const uint8_t* key, const uint8_t* iv, int encrypt); 247 248 /** 249 * Use a previously created cipher context to encrypt the given plain text. 250 */ 251 WOLFSSL_API 252 int wolfSSL_quic_aead_encrypt(uint8_t* dest, WOLFSSL_EVP_CIPHER_CTX* aead_ctx, 253 const uint8_t* plain, size_t plainlen, 254 const uint8_t* iv, const uint8_t* aad, 255 size_t aadlen); 256 /** 257 * Use a previously created cipher context to decrypt the given encoded text. 258 */ 259 WOLFSSL_API 260 int wolfSSL_quic_aead_decrypt(uint8_t* dest, WOLFSSL_EVP_CIPHER_CTX* ctx, 261 const uint8_t* enc, size_t enclen, 262 const uint8_t* iv, const uint8_t* aad, 263 size_t aadlen); 264 265 /** 266 * Extract a pseudo-random key, using the given message digest, a secret 267 * and a salt. The key size is the size of the digest. 268 */ 269 WOLFSSL_API 270 int wolfSSL_quic_hkdf_extract(uint8_t* dest, const WOLFSSL_EVP_MD* md, 271 const uint8_t* secret, size_t secretlen, 272 const uint8_t* salt, size_t saltlen); 273 /** 274 * Expand a pseudo-random key (secret) into a new key, using the mesasge 275 * digest and the info bytes. 276 */ 277 WOLFSSL_API 278 int wolfSSL_quic_hkdf_expand(uint8_t* dest, size_t destlen, 279 const WOLFSSL_EVP_MD* md, 280 const uint8_t* secret, size_t secretlen, 281 const uint8_t* info, size_t infolen); 282 283 /** 284 * Extract and extpand secret, salt and info into a new key. 285 */ 286 WOLFSSL_API 287 int wolfSSL_quic_hkdf(uint8_t* dest, size_t destlen, 288 const WOLFSSL_EVP_MD* md, 289 const uint8_t* secret, size_t secretlen, 290 const uint8_t* salt, size_t saltlen, 291 const uint8_t* info, size_t infolen); 292 293 /* most common QUIC packet size as of 2022 was 1,200 bytes 294 * largest packet size listed in the RFC is 1,392 bytes 295 * this gives plenty of breathing room for capacity of records but keeps sizes 296 * read from the wire sane */ 297 #ifndef WOLFSSL_QUIC_MAX_RECORD_CAPACITY 298 /* 1024*1024 -- 1 MB */ 299 #define WOLFSSL_QUIC_MAX_RECORD_CAPACITY (1048576) 300 #endif 301 302 #endif /* WOLFSSL_QUIC */ 303 304 #ifdef __cplusplus 305 } /* extern "C" */ 306 #endif 307 308 #endif /* WOLFSSL_QUIC_H */