Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

quic: update deps for quic draft 29 #34033

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
199 changes: 94 additions & 105 deletions deps/ngtcp2/crypto/includes/ngtcp2/ngtcp2_crypto.h
Expand Up @@ -175,7 +175,7 @@ ngtcp2_crypto_packet_protection_ivlen(const ngtcp2_crypto_aead *aead);
/**
* @function
*
* `ngtcp2_crypto_derive_packet_protection_key` dervies packet
* `ngtcp2_crypto_derive_packet_protection_key` derives packet
* protection key. This function writes packet protection key into
* the buffer pointed by |key|. |key| must point to the buffer which
* is at least ngtcp2_crypto_aead_keylen(aead) bytes long. This
Expand Down Expand Up @@ -237,7 +237,7 @@ ngtcp2_crypto_encrypt_cb(uint8_t *dest, const ngtcp2_crypto_aead *aead,
* `ngtcp2_crypto_decrypt` decrypts |ciphertext| of length
* |ciphertextlen| and writes the plaintext into the buffer pointed by
* |dest|. The length of plaintext is ciphertextlen -
* ngtcp2_crypto_aead_taglen(aead) bytes log. |dest| must have enough
* ngtcp2_crypto_aead_taglen(aead) bytes long. |dest| must have enough
* capacity to store the plaintext. It is allowed to specify the same
* value to |dest| and |ciphertext|.
*
Expand Down Expand Up @@ -298,32 +298,17 @@ NGTCP2_EXTERN int ngtcp2_crypto_hp_mask_cb(uint8_t *dest,
/**
* @function
*
* `ngtcp2_crypto_derive_and_install_key` derives the rx and tx keys
* from |rx_secret| and |tx_secret| respectively and installs new keys
* to |conn|.
* `ngtcp2_crypto_derive_and_install_rx_key` derives the rx keys from
* |secret| and installs new keys to |conn|.
*
* If |key| is not NULL, the derived packet protection key for
* decryption is written to the buffer pointed by |key|. If |iv| is
* not NULL, the derived packet protection IV for decryption is
* written to the buffer pointed by |iv|. If |hp| is not NULL, the
* derived header protection key for decryption is written to the
* buffer pointed by |hp|.
*
* If |rx_key| is not NULL, the derived packet protection key for
* decryption is written to the buffer pointed by |rx_key|. If
* |rx_iv| is not NULL, the derived packet protection IV for
* decryption is written to the buffer pointed by |rx_iv|. If |rx_hp|
* is not NULL, the derived header protection key for decryption is
* written to the buffer pointed by |rx_hp|.
*
* If |tx_key| is not NULL, the derived packet protection key for
* encryption is written to the buffer pointed by |tx_key|. If
* |tx_iv| is not NULL, the derived packet protection IV for
* encryption is written to the buffer pointed by |tx_iv|. If |tx_hp|
* is not NULL, the derived header protection key for encryption is
* written to the buffer pointed by |tx_hp|.
*
* |level| specifies the encryption level. If |level| is
* NGTCP2_CRYPTO_LEVEL_EARLY, and if |side| is
* NGTCP2_CRYPTO_SIDE_CLIENT, |rx_secret| must be NULL. If |level| is
* NGTCP2_CRYPTO_LEVEL_EARLY, and if |side| is
* NGTCP2_CRYPTO_SIDE_SERVER, |tx_secret| must be NULL. Otherwise,
* |rx_secret| and |tx_secret| must not be NULL.
*
* |secretlen| specifies the length of |rx_secret| and |tx_secret|.
* |secretlen| specifies the length of |secret|.
*
* The length of packet protection key and header protection key is
* ngtcp2_crypto_aead(ctx->aead), and the length of packet protection
Expand All @@ -337,71 +322,48 @@ NGTCP2_EXTERN int ngtcp2_crypto_hp_mask_cb(uint8_t *dest,
* It also calls `ngtcp2_conn_set_aead_overhead` to set AEAD tag
* length.
*
* If |level| is NGTCP2_CRYPTO_LEVEL_APP, this function retrieves a
* remote QUIC transport parameters extension from |tls| and sets it
* to |conn|.
*
* This function returns 0 if it succeeds, or -1.
*/
NGTCP2_EXTERN int ngtcp2_crypto_derive_and_install_key(
ngtcp2_conn *conn, void *tls, uint8_t *rx_key, uint8_t *rx_iv,
uint8_t *rx_hp, uint8_t *tx_key, uint8_t *tx_iv, uint8_t *tx_hp,
ngtcp2_crypto_level level, const uint8_t *rx_secret,
const uint8_t *tx_secret, size_t secretlen, ngtcp2_crypto_side side);
NGTCP2_EXTERN int ngtcp2_crypto_derive_and_install_rx_key(
ngtcp2_conn *conn, uint8_t *key, uint8_t *iv, uint8_t *hp,
ngtcp2_crypto_level level, const uint8_t *secret, size_t secretlen);

/**
* @function
*
* `ngtcp2_crypto_derive_and_install_initial_key` derives initial
* keying materials and installs keys to |conn|.
*
* If |rx_secret| is not NULL, the secret for decryption is written to
* the buffer pointed by |rx_secret|. The length of secret is 32
* bytes, and |rx_secret| must point to the buffer which has enough
* capacity.
*
* If |tx_secret| is not NULL, the secret for encryption is written to
* the buffer pointed by |tx_secret|. The length of secret is 32
* bytes, and |tx_secret| must point to the buffer which has enough
* capacity.
*
* If |initial_secret| is not NULL, the initial secret is written to
* the buffer pointed by |initial_secret|. The length of secret is 32
* bytes, and |initial_secret| must point to the buffer which has
* enough capacity.
*
* |client_dcid| is the destination connection ID in first Initial
* packet of client.
*
* If |rx_key| is not NULL, the derived packet protection key for
* decryption is written to the buffer pointed by |rx_key|. If
* |rx_iv| is not NULL, the derived packet protection IV for
* decryption is written to the buffer pointed by |rx_iv|. If |rx_hp|
* is not NULL, the derived header protection key for decryption is
* written to the buffer pointed by |rx_hp|.
*
* If |tx_key| is not NULL, the derived packet protection key for
* encryption is written to the buffer pointed by |tx_key|. If
* |tx_iv| is not NULL, the derived packet protection IV for
* encryption is written to the buffer pointed by |tx_iv|. If |tx_hp|
* is not NULL, the derived header protection key for encryption is
* written to the buffer pointed by |tx_hp|.
*
* The length of packet protection key and header protection key is 16
* bytes long. The length of packet protection IV is 12 bytes long.
*
* This function calls `ngtcp2_conn_set_initial_crypto_ctx` to set
* initial AEAD and message digest algorithm. After the successful
* call of this function, application can use
* `ngtcp2_conn_get_initial_crypto_ctx` to get the object.
* `ngtcp2_crypto_derive_and_install_tx_key` derives the tx keys from
* |secret| and installs new keys to |conn|.
*
* If |key| is not NULL, the derived packet protection key for
* encryption is written to the buffer pointed by |key|. If |iv| is
* not NULL, the derived packet protection IV for encryption is
* written to the buffer pointed by |iv|. If |hp| is not NULL, the
* derived header protection key for encryption is written to the
* buffer pointed by |hp|.
*
* |secretlen| specifies the length of |secret|.
*
* The length of packet protection key and header protection key is
* ngtcp2_crypto_aead(ctx->aead), and the length of packet protection
* IV is ngtcp2_crypto_packet_protection_ivlen(ctx->aead) where ctx
* can be obtained by `ngtcp2_crypto_ctx_tls`.
*
* In the first call of this function, it calls
* `ngtcp2_conn_set_crypto_ctx` to set negotiated AEAD and message
* digest algorithm. After the successful call of this function,
* application can use `ngtcp2_conn_get_crypto_ctx` to get the object.
* It also calls `ngtcp2_conn_set_aead_overhead` to set AEAD tag
* length.
*
* If |level| is NGTCP2_CRYPTO_LEVEL_APP, this function retrieves a
* remote QUIC transport parameters extension from |tls| and sets it
* to |conn|.
*
* This function returns 0 if it succeeds, or -1.
*/
NGTCP2_EXTERN int ngtcp2_crypto_derive_and_install_initial_key(
ngtcp2_conn *conn, uint8_t *rx_secret, uint8_t *tx_secret,
uint8_t *initial_secret, uint8_t *rx_key, uint8_t *rx_iv, uint8_t *rx_hp,
uint8_t *tx_key, uint8_t *tx_iv, uint8_t *tx_hp,
const ngtcp2_cid *client_dcid, ngtcp2_crypto_side side);
NGTCP2_EXTERN int ngtcp2_crypto_derive_and_install_tx_key(
ngtcp2_conn *conn, uint8_t *key, uint8_t *iv, uint8_t *hp,
ngtcp2_crypto_level level, const uint8_t *secret, size_t secretlen);

/**
* @function
Expand Down Expand Up @@ -458,6 +420,54 @@ NGTCP2_EXTERN int ngtcp2_crypto_update_key_cb(
const uint8_t *current_rx_secret, const uint8_t *current_tx_secret,
size_t secretlen, void *user_data);

/**
* @function
*
* `ngtcp2_crypto_client_initial_cb` installs initial secrets and
* encryption keys and sets QUIC transport parameters.
*
* This function can be directly passed to client_initial field in
* ngtcp2_callbacks. It is only used by client.
*
* This function returns 0 if it succeeds, or
* :enum:`NGTCP2_ERR_CALLBACK_FAILURE`.
*/
NGTCP2_EXTERN int ngtcp2_crypto_client_initial_cb(ngtcp2_conn *conn,
void *user_data);

/**
* @function
*
* `ngtcp2_crypto_recv_retry_cb` re-installs initial secrets in
* response to incoming Retry packet.
*
* This function can be directly passed to recv_retry field in
* ngtcp2_callbacks. It is only used by client.
*
* This function returns 0 if it succeeds, or
* :enum:`NGTCP2_ERR_CALLBACK_FAILURE`.
*/
NGTCP2_EXTERN int ngtcp2_crypto_recv_retry_cb(ngtcp2_conn *conn,
const ngtcp2_pkt_hd *hd,
void *user_data);

/**
* @function
*
* `ngtcp2_crypto_recv_client_initial_cb` installs initial secrets in
* response to an incoming Initial packet from client, and sets QUIC
* transport parameters.
*
* This function can be directly passed to recv_client_initial field
* in ngtcp2_callbacks. It is only used by server.
*
* This function returns 0 if it succeeds, or
* :enum:`NGTCP2_ERR_CALLBACK_FAILURE`.
*/
NGTCP2_EXTERN int ngtcp2_crypto_recv_client_initial_cb(ngtcp2_conn *conn,
const ngtcp2_cid *dcid,
void *user_data);

/**
* @function
*
Expand All @@ -468,38 +478,17 @@ NGTCP2_EXTERN int ngtcp2_crypto_update_key_cb(
* allowed to call this function with datalen == 0. In this case, no
* additional read operation is done.
*
* |tls| points to a implementation dependent TLS session object. If
* libngtcp2_crypto_openssl is linked, |tls| must be a pointer to SSL
* object.
*
* This function returns 0 if it succeeds, or a negative error code.
* The generic error code is -1 if a specific error code is not
* suitable. The error codes less than -10000 are specific to
* underlying TLS implementation. For OpenSSL, the error codes are
* defined in ngtcp2_crypto_openssl.h.
*/
NGTCP2_EXTERN int
ngtcp2_crypto_read_write_crypto_data(ngtcp2_conn *conn, void *tls,
ngtcp2_crypto_read_write_crypto_data(ngtcp2_conn *conn,
ngtcp2_crypto_level crypto_level,
const uint8_t *data, size_t datalen);

/**
* @function
*
* `ngtcp2_crypto_set_remote_transport_params` retrieves a remote QUIC
* transport parameters from |tls| and sets it to |conn| using
* `ngtcp2_conn_set_remote_transport_params`.
*
* |tls| points to a implementation dependent TLS session object. If
* libngtcp2_crypto_openssl is linked, |tls| must be a pointer to SSL
* object.
*
* This function returns 0 if it succeeds, or -1.
*/
NGTCP2_EXTERN int
ngtcp2_crypto_set_remote_transport_params(ngtcp2_conn *conn, void *tls,
ngtcp2_crypto_side side);

/**
* @function
*
Expand Down
56 changes: 49 additions & 7 deletions deps/ngtcp2/crypto/openssl/openssl.c
Expand Up @@ -35,10 +35,14 @@
#include <openssl/evp.h>
#include <openssl/kdf.h>

#include "shared.h"

ngtcp2_crypto_ctx *ngtcp2_crypto_ctx_initial(ngtcp2_crypto_ctx *ctx) {
ctx->aead.native_handle = (void *)EVP_aes_128_gcm();
ctx->md.native_handle = (void *)EVP_sha256();
ctx->hp.native_handle = (void *)EVP_aes_128_ctr();
ctx->max_encryption = 0;
ctx->max_decryption_failure = 0;
return ctx;
}

Expand All @@ -62,6 +66,34 @@ static const EVP_CIPHER *crypto_ssl_get_aead(SSL *ssl) {
}
}

static uint64_t crypto_ssl_get_aead_max_encryption(SSL *ssl) {
switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl))) {
case TLS1_3_CK_AES_128_GCM_SHA256:
case TLS1_3_CK_AES_256_GCM_SHA384:
return NGTCP2_CRYPTO_MAX_ENCRYPTION_AES_GCM;
case TLS1_3_CK_CHACHA20_POLY1305_SHA256:
return NGTCP2_CRYPTO_MAX_ENCRYPTION_CHACHA20_POLY1305;
case TLS1_3_CK_AES_128_CCM_SHA256:
return NGTCP2_CRYPTO_MAX_ENCRYPTION_AES_CCM;
default:
return 0;
}
}

static uint64_t crypto_ssl_get_aead_max_decryption_failure(SSL *ssl) {
switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl))) {
case TLS1_3_CK_AES_128_GCM_SHA256:
case TLS1_3_CK_AES_256_GCM_SHA384:
return NGTCP2_CRYPTO_MAX_DECRYPTION_FAILURE_AES_GCM;
case TLS1_3_CK_CHACHA20_POLY1305_SHA256:
return NGTCP2_CRYPTO_MAX_DECRYPTION_FAILURE_CHACHA20_POLY1305;
case TLS1_3_CK_AES_128_CCM_SHA256:
return NGTCP2_CRYPTO_MAX_DECRYPTION_FAILURE_AES_CCM;
default:
return 0;
}
}

static const EVP_CIPHER *crypto_ssl_get_hp(SSL *ssl) {
switch (SSL_CIPHER_get_id(SSL_get_current_cipher(ssl))) {
case TLS1_3_CK_AES_128_GCM_SHA256:
Expand Down Expand Up @@ -95,6 +127,8 @@ ngtcp2_crypto_ctx *ngtcp2_crypto_ctx_tls(ngtcp2_crypto_ctx *ctx,
ctx->aead.native_handle = (void *)crypto_ssl_get_aead(ssl);
ctx->md.native_handle = (void *)crypto_ssl_get_md(ssl);
ctx->hp.native_handle = (void *)crypto_ssl_get_hp(ssl);
ctx->max_encryption = crypto_ssl_get_aead_max_encryption(ssl);
ctx->max_decryption_failure = crypto_ssl_get_aead_max_decryption_failure(ssl);
return ctx;
}

Expand Down Expand Up @@ -313,10 +347,10 @@ from_ngtcp2_level(ngtcp2_crypto_level crypto_level) {
}
}

int ngtcp2_crypto_read_write_crypto_data(ngtcp2_conn *conn, void *tls,
int ngtcp2_crypto_read_write_crypto_data(ngtcp2_conn *conn,
ngtcp2_crypto_level crypto_level,
const uint8_t *data, size_t datalen) {
SSL *ssl = tls;
SSL *ssl = ngtcp2_conn_get_tls_native_handle(conn);
int rv;
int err;

Expand Down Expand Up @@ -365,13 +399,12 @@ int ngtcp2_crypto_read_write_crypto_data(ngtcp2_conn *conn, void *tls,
return 0;
}

int ngtcp2_crypto_set_remote_transport_params(ngtcp2_conn *conn, void *tls,
ngtcp2_crypto_side side) {
int ngtcp2_crypto_set_remote_transport_params(ngtcp2_conn *conn, void *tls) {
SSL *ssl = tls;
ngtcp2_transport_params_type exttype =
side == NGTCP2_CRYPTO_SIDE_CLIENT
? NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS
: NGTCP2_TRANSPORT_PARAMS_TYPE_CLIENT_HELLO;
ngtcp2_conn_is_server(conn)
? NGTCP2_TRANSPORT_PARAMS_TYPE_CLIENT_HELLO
: NGTCP2_TRANSPORT_PARAMS_TYPE_ENCRYPTED_EXTENSIONS;
const uint8_t *tp;
size_t tplen;
ngtcp2_transport_params params;
Expand All @@ -393,3 +426,12 @@ int ngtcp2_crypto_set_remote_transport_params(ngtcp2_conn *conn, void *tls,

return 0;
}

int ngtcp2_crypto_set_local_transport_params(void *tls, const uint8_t *buf,
size_t len) {
if (SSL_set_quic_transport_params(tls, buf, len) != 1) {
return -1;
}

return 0;
}