123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- /* quic.h
- *
- * Copyright (C) 2006-2023 wolfSSL Inc.
- *
- * This file is part of wolfSSL.
- *
- * wolfSSL is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * wolfSSL is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
- */
- /* wolfSSL QUIC API */
- #ifndef WOLFSSL_QUIC_H
- #define WOLFSSL_QUIC_H
- #ifdef __cplusplus
- extern "C" {
- #endif
- #ifdef WOLFSSL_QUIC
- #include <stdint.h>
- /* QUIC operates on three encryption levels which determine
- * which keys/algos are used for de-/encryption. These are
- * kept separately for incoming and outgoing data and.
- * Due to the nature of UDP, more than one might be in use
- * at the same time due to resends or out-of-order arrivals.
- */
- typedef enum wolfssl_encryption_level_t {
- wolfssl_encryption_initial = 0,
- wolfssl_encryption_early_data,
- wolfssl_encryption_handshake,
- wolfssl_encryption_application
- } WOLFSSL_ENCRYPTION_LEVEL;
- /* All QUIC related callbacks to the application.
- */
- typedef struct wolfssl_quic_method_t WOLFSSL_QUIC_METHOD;
- struct wolfssl_quic_method_t {
- /**
- * Provide secrets to the QUIC stack when they become available in the SSL
- * instance during handshake processing. read/write secrets have the same
- * length. A call may only provide one, passing NULL as the other.
- */
- int (*set_encryption_secrets)(WOLFSSL* ssl, WOLFSSL_ENCRYPTION_LEVEL level,
- const uint8_t* read_secret,
- const uint8_t* write_secret,
- size_t secret_len);
- /**
- * Provide handshake packets to the QUIC stack to send to the peer. The
- * QUIC stack will wrap these and take care of re-transmissions.
- */
- int (*add_handshake_data)(WOLFSSL* ssl, WOLFSSL_ENCRYPTION_LEVEL level,
- const uint8_t* data, size_t len);
- /**
- * Flush any buffered packets during handshake.
- */
- int (*flush_flight)(WOLFSSL* ssl);
- /**
- * Send a TLS alert that happened during handshake. In QUIC, such alerts
- * lead to connection shutdown.
- */
- int (*send_alert)(WOLFSSL* ssl, WOLFSSL_ENCRYPTION_LEVEL level,
- uint8_t alert);
- };
- /**
- * Mark the given SSL context for QUIC protocol handling. Meaning all
- * SSL instances derived from it will inherit this. Provides all callbacks
- * to the QUIC application the SSL stack needs.
- */
- WOLFSSL_API
- int wolfSSL_CTX_set_quic_method(WOLFSSL_CTX* ctx,
- const WOLFSSL_QUIC_METHOD* quic_method);
- /**
- * Mark exactly this SSL instance for QUIC protocol handling.
- * Provides all callbacks to the QUIC application the SSL stack needs.
- */
- WOLFSSL_API
- int wolfSSL_set_quic_method(WOLFSSL* ssl,
- const WOLFSSL_QUIC_METHOD* quic_method);
- /**
- * Check if QUIC handling has been installed on the given SSL instance.
- */
- WOLFSSL_API int wolfSSL_is_quic(WOLFSSL* ssl);
- /**
- * Return the current encryption level of the SSL instance for READs.
- */
- WOLFSSL_API
- WOLFSSL_ENCRYPTION_LEVEL wolfSSL_quic_read_level(const WOLFSSL* ssl);
- /**
- * Return the current encryption level of the SSL instance for WRITEs.
- */
- WOLFSSL_API
- WOLFSSL_ENCRYPTION_LEVEL wolfSSL_quic_write_level(const WOLFSSL* ssl);
- /**
- * Configure the QUIC transport version to use. On `use_legacy` != 0,
- * selects TLSX_KEY_QUIC_TP_PARAMS_DRAFT, otherwise TLSX_KEY_QUIC_TP_PARAMS.
- * This method is part of the BoringSSL API and replicated here for app
- * portability (as in quictls/openssl).
- */
- WOLFSSL_API
- void wolfSSL_set_quic_use_legacy_codepoint(WOLFSSL* ssl, int use_legacy);
- /**
- * Set the TLS extension for the transport parameter version to announce
- * to the peer. Known values are TLSX_KEY_QUIC_TP_PARAMS (V1) and
- * TLSX_KEY_QUIC_TP_PARAMS_DRAFT.
- * Setting it to 0 will announce both V1 and draft versions to a server.
- * Servers will, on 0, select the latest version seen from the client.
- * Default is 0.
- */
- WOLFSSL_API
- void wolfSSL_set_quic_transport_version(WOLFSSL* ssl, int version);
- /**
- * Get the configured transport version.
- */
- WOLFSSL_API int wolfSSL_get_quic_transport_version(const WOLFSSL* ssl);
- /**
- * Set the raw QUIC transport parameter that will be sent in the TLS extension
- * to the peer, using the configured transport version(s).
- */
- WOLFSSL_API int wolfSSL_set_quic_transport_params(WOLFSSL* ssl,
- const uint8_t* params,
- size_t params_len);
- /**
- * Get the raw QUIC transport parameter as retrieved via TLS Extension
- * from the peer. If the peer announced several versions,
- * return the latest one.
- * If the extension has not arrived yet, initializes out parameter to
- * NULL, resp. 0.
- */
- WOLFSSL_API
- void wolfSSL_get_peer_quic_transport_params(const WOLFSSL* ssl,
- const uint8_t* *out_params,
- size_t* out_params_len);
- /**
- * Get the QUIC version negotiated with the peer during the handshake.
- */
- WOLFSSL_API int wolfSSL_get_peer_quic_transport_version(const WOLFSSL* ssl);
- #ifdef WOLFSSL_EARLY_DATA
- WOLFSSL_API void wolfSSL_set_quic_early_data_enabled(WOLFSSL* ssl, int enabled);
- #endif
- /**
- * Advisory amount of the maximum data a QUIC protocol handler should have
- * in flight. This varies during handshake processing, for example certificate
- * exchange will increase the limit.
- */
- WOLFSSL_API
- size_t wolfSSL_quic_max_handshake_flight_len(const WOLFSSL* ssl,
- WOLFSSL_ENCRYPTION_LEVEL level);
- /**
- * The QUIC protocol handler provides peer TLS records to the SSL instance
- * during handshake to progress it. The SSL instance will use the registered
- * callbacks to send packets to the peer.
- * Encryption level is provided to indicate how to decrypt the data. Data may
- * be added for levels not yet reached by the SSL instance. However, data
- * may only be added in ever increasing levels and levels may only increase
- * at TLS record boundaries. Any violation will make this function fail.
- */
- WOLFSSL_API
- int wolfSSL_provide_quic_data(WOLFSSL* ssl, WOLFSSL_ENCRYPTION_LEVEL level,
- const uint8_t* data, size_t len);
- WOLFSSL_API
- int wolfSSL_quic_do_handshake(WOLFSSL* ssl);
- /**
- * Process any CRYPTO data added post-handshake.
- */
- WOLFSSL_API int wolfSSL_process_quic_post_handshake(WOLFSSL* ssl);
- /**
- * Process any pending input and flush all output. Can be invoked
- * during and/or after handshake processing.
- */
- WOLFSSL_API int wolfSSL_quic_read_write(WOLFSSL* ssl);
- /**
- * Get the AEAD cipher that is currently selected in the SSL instance.
- * Will return NULL if none has been selected so far. This is used by the
- * QUIC stack to encrypt/decrypt packets after the handshake.
- */
- WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_quic_get_aead(WOLFSSL* ssl);
- /**
- * Use to classify the AEAD cipher for key reuse limits.
- */
- WOLFSSL_API int wolfSSL_quic_aead_is_gcm(const WOLFSSL_EVP_CIPHER* aead_cipher);
- WOLFSSL_API int wolfSSL_quic_aead_is_ccm(const WOLFSSL_EVP_CIPHER* aead_cipher);
- WOLFSSL_API
- int wolfSSL_quic_aead_is_chacha20(const WOLFSSL_EVP_CIPHER* aead_cipher);
- /**
- * Get the 'tag' length used by the AEAD cipher. Encryption buffer lengths
- * are plaintext length plus this tag length.
- */
- WOLFSSL_API
- size_t wolfSSL_quic_get_aead_tag_len(const WOLFSSL_EVP_CIPHER* aead_cipher);
- /**
- * The message digest currently selected in the SSL instance.
- */
- WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_quic_get_md(WOLFSSL* ssl);
- /**
- * The QUIC header protection cipher matching the AEAD cipher currently
- * selected in the SSL instance.
- */
- WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_quic_get_hp(WOLFSSL* ssl);
- /**
- * Create and initialize a cipher context for use in en- or decryption.
- */
- WOLFSSL_API WOLFSSL_EVP_CIPHER_CTX*
- wolfSSL_quic_crypt_new(const WOLFSSL_EVP_CIPHER* cipher,
- const uint8_t* key, const uint8_t* iv, int encrypt);
- /**
- * Use a previously created cipher context to encrypt the given plain text.
- */
- WOLFSSL_API
- int wolfSSL_quic_aead_encrypt(uint8_t* dest, WOLFSSL_EVP_CIPHER_CTX* aead_ctx,
- const uint8_t* plain, size_t plainlen,
- const uint8_t* iv, const uint8_t* aad,
- size_t aadlen);
- /**
- * Use a previously created cipher context to decrypt the given encoded text.
- */
- WOLFSSL_API
- int wolfSSL_quic_aead_decrypt(uint8_t* dest, WOLFSSL_EVP_CIPHER_CTX* ctx,
- const uint8_t* enc, size_t enclen,
- const uint8_t* iv, const uint8_t* aad,
- size_t aadlen);
- /**
- * Extract a pseudo-random key, using the given message digest, a secret
- * and a salt. The key size is the size of the digest.
- */
- WOLFSSL_API
- int wolfSSL_quic_hkdf_extract(uint8_t* dest, const WOLFSSL_EVP_MD* md,
- const uint8_t* secret, size_t secretlen,
- const uint8_t* salt, size_t saltlen);
- /**
- * Expand a pseudo-random key (secret) into a new key, using the mesasge
- * digest and the info bytes.
- */
- WOLFSSL_API
- int wolfSSL_quic_hkdf_expand(uint8_t* dest, size_t destlen,
- const WOLFSSL_EVP_MD* md,
- const uint8_t* secret, size_t secretlen,
- const uint8_t* info, size_t infolen);
- /**
- * Extract and extpand secret, salt and info into a new key.
- */
- WOLFSSL_API
- int wolfSSL_quic_hkdf(uint8_t* dest, size_t destlen,
- const WOLFSSL_EVP_MD* md,
- const uint8_t* secret, size_t secretlen,
- const uint8_t* salt, size_t saltlen,
- const uint8_t* info, size_t infolen);
- /* most common QUIC packet size as of 2022 was 1,200 bytes
- * largest packet size listed in the RFC is 1,392 bytes
- * this gives plenty of breathing room for capacity of records but keeps sizes
- * read from the wire sane */
- #ifndef WOLFSSL_QUIC_MAX_RECORD_CAPACITY
- /* 1024*1024 -- 1 MB */
- #define WOLFSSL_QUIC_MAX_RECORD_CAPACITY (1048576)
- #endif
- #endif /* WOLFSSL_QUIC */
- #ifdef __cplusplus
- } /* extern "C" */
- #endif
- #endif /* WOLFSSL_QUIC_H */
|