QUIC: fix 0-RTT decryption for ciphers using SHA-256

Do not limit the digest function for 0-RTT ciphers to SHA-384, add
support for digest algorithms with smaller output sizes such as SHA-256.

Fixes 0-RTT decryption of quic_0-rtt_cannot_decrypt-dsb.pcapng
(draft -23).

Change-Id: I3b49d17497fbfa52773a989dc530d04b37b20c3a
Ping-Bug: 13881
Reviewed-on: https://code.wireshark.org/review/35144
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot
Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
This commit is contained in:
Peter Wu 2019-11-19 23:40:07 +00:00 committed by Alexis La Goutte
parent 309bf5b547
commit dc2b424e0a
3 changed files with 10 additions and 13 deletions

View File

@ -1606,7 +1606,7 @@ quic_create_decoders(packet_info *pinfo, quic_info_data_t *quic_info, quic_ciphe
guint hash_len = gcry_md_get_algo_dlen(quic_info->hash_algo);
char *secret = (char *)wmem_alloc0(wmem_packet_scope(), hash_len);
if (!tls13_get_quic_secret(pinfo, from_server, type, hash_len, secret)) {
if (!tls13_get_quic_secret(pinfo, from_server, type, hash_len, hash_len, secret)) {
*error = "Secrets are not available";
return FALSE;
}
@ -1627,7 +1627,7 @@ quic_get_traffic_secret(packet_info *pinfo, int hash_algo, quic_pp_state_t *pp_s
{
guint hash_len = gcry_md_get_algo_dlen(hash_algo);
char *secret = (char *)wmem_alloc0(wmem_packet_scope(), hash_len);
if (!tls13_get_quic_secret(pinfo, !from_client, TLS_SECRET_APP, hash_len, secret)) {
if (!tls13_get_quic_secret(pinfo, !from_client, TLS_SECRET_APP, hash_len, hash_len, secret)) {
return FALSE;
}
pp_state->next_secret = (guint8 *)wmem_memdup(wmem_file_scope(), secret, hash_len);
@ -1970,6 +1970,7 @@ dissect_quic_long_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tre
}
/* Prepare the Initial/Handshake cipher for header/payload decryption. */
if (!PINFO_FD_VISITED(pinfo) && conn && cipher) {
#define DIGEST_MIN_SIZE 32 /* SHA256 */
#define DIGEST_MAX_SIZE 48 /* SHA384 */
const gchar *error = NULL;
gchar early_data_secret[DIGEST_MAX_SIZE];
@ -1980,7 +1981,7 @@ dissect_quic_long_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *quic_tre
* ID from the *very first* Client Initial packet. */
quic_create_initial_decoders(&dcid, &error, conn);
} else if (long_packet_type == QUIC_LPT_0RTT) {
early_data_secret_len = tls13_get_quic_secret(pinfo, FALSE, TLS_SECRET_0RTT_APP, DIGEST_MAX_SIZE, early_data_secret);
early_data_secret_len = tls13_get_quic_secret(pinfo, FALSE, TLS_SECRET_0RTT_APP, DIGEST_MIN_SIZE, DIGEST_MAX_SIZE, early_data_secret);
if (early_data_secret_len == 0) {
error = "Secrets are not available";
}

View File

@ -3806,11 +3806,11 @@ tls_get_cipher_info(packet_info *pinfo, guint16 cipher_suite, int *cipher_algo,
/**
* Load the QUIC traffic secret from the keylog file.
* Returns the secret length (at most 'secret_size') and the secret into
* Returns the secret length (at most 'secret_max_len') and the secret into
* 'secret' if a secret was found, or zero otherwise.
*/
gint
tls13_get_quic_secret(packet_info *pinfo, gboolean is_from_server, int type, guint secret_len, guint8 *secret_out)
tls13_get_quic_secret(packet_info *pinfo, gboolean is_from_server, int type, guint secret_min_len, guint secret_max_len, guint8 *secret_out)
{
GHashTable *key_map;
const char *label;
@ -3869,19 +3869,15 @@ tls13_get_quic_secret(packet_info *pinfo, gboolean is_from_server, int type, gui
}
StringInfo *secret = (StringInfo *)g_hash_table_lookup(key_map, &ssl->client_random);
if (!secret || secret->data_len != secret_len) {
ssl_debug_printf("%s Cannot find QUIC %s of size %d, found bad size %d!\n",
G_STRFUNC, label, secret_len, secret ? secret->data_len : 0);
if (!secret || secret->data_len < secret_min_len || secret->data_len > secret_max_len) {
ssl_debug_printf("%s Cannot find QUIC %s of size %d..%d, found bad size %d!\n",
G_STRFUNC, label, secret_min_len, secret_max_len, secret ? secret->data_len : 0);
return 0;
}
ssl_debug_printf("%s Retrieved QUIC traffic secret.\n", G_STRFUNC);
ssl_print_string("Client Random", &ssl->client_random);
ssl_print_string(label, secret);
if (secret->data_len > secret_len) {
ssl_debug_printf("%s Output buffer size is too small!\n", G_STRFUNC);
return 0;
}
memcpy(secret_out, secret->data, secret->data_len);
return secret->data_len;
}

View File

@ -46,7 +46,7 @@ tls13_exporter(packet_info *pinfo, gboolean is_early,
guint context_length, guint key_length, guchar **out);
gint
tls13_get_quic_secret(packet_info *pinfo, gboolean is_from_server, int type, guint secret_len, guint8 *secret_out);
tls13_get_quic_secret(packet_info *pinfo, gboolean is_from_server, int type, guint secret_min_len, guint secret_max_len, guint8 *secret_out);
/**
* Returns the application-layer protocol name (ALPN) for the current TLS