aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2019-11-20 00:51:02 +0000
committerAlexis La Goutte <alexis.lagoutte@gmail.com>2019-11-20 04:12:24 +0000
commit71e03ef0423ef5215f8b4843433dc623ad1df74a (patch)
tree79e1e557c1e11cfddc7ab7d34da4b9efbbadea8d
parentdc2b424e0a3dc3ca07d69b1ca20571bb070d5a3b (diff)
QUIC: updates for Key Phase changes (draft -24)
Fix decryption after Key Updates due to a HKDF label change, add a new error code, and rename KEY_PHASE to be consistent with draft 24. Change-Id: I73858112a6b4afd2b6de8f7183f4c4edaf03f705 Ping-Bug: 13881 Reviewed-on: https://code.wireshark.org/review/35145 Petri-Dish: Peter Wu <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
-rw-r--r--epan/dissectors/packet-quic.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/epan/dissectors/packet-quic.c b/epan/dissectors/packet-quic.c
index 2b5f4b0c02..a42244fb6c 100644
--- a/epan/dissectors/packet-quic.c
+++ b/epan/dissectors/packet-quic.c
@@ -226,7 +226,7 @@ typedef struct quic_cipher {
*/
typedef struct quic_pp_state {
guint8 *next_secret; /**< Next application traffic secret. */
- quic_cipher cipher[2]; /**< Cipher for KEY_PHASE 0/1 */
+ quic_cipher cipher[2]; /**< Cipher for Key Phase 0/1 */
guint64 changed_in_pkn; /**< Packet number where key change occurred. */
gboolean key_phase : 1; /**< Current key phase. */
} quic_pp_state_t;
@@ -452,6 +452,7 @@ static const range_string quic_transport_error_code_vals[] = {
{ 0x0008, 0x0008, "TRANSPORT_PARAMETER_ERROR" },
{ 0x000A, 0x000A, "PROTOCOL_VIOLATION" },
{ 0x000D, 0x000D, "CRYPTO_BUFFER_EXCEEDED" },
+ { 0x000E, 0x000E, "KEY_UPDATE_ERROR" },
{ 0x0100, 0x01FF, "CRYPTO_ERROR" },
/* 0x40 - 0x3fff Assigned via Specification Required policy. */
{ 0, 0, NULL }
@@ -1663,11 +1664,12 @@ quic_cipher_init(quic_cipher *cipher, int hash_algo, guint8 key_length, guint8 *
* Updates the packet protection secret to the next one.
*/
static void
-quic_update_key(int hash_algo, quic_pp_state_t *pp_state)
+quic_update_key(guint32 version, int hash_algo, quic_pp_state_t *pp_state)
{
guint hash_len = gcry_md_get_algo_dlen(hash_algo);
+ const char *label = is_quic_draft_max(version, 23) ? "traffic upd" : "quic ku";
gboolean ret = quic_hkdf_expand_label(hash_algo, pp_state->next_secret, hash_len,
- "traffic upd", pp_state->next_secret, hash_len);
+ label, pp_state->next_secret, hash_len);
/* This must always succeed as our hash algorithm was already validated. */
DISSECTOR_ASSERT(ret);
}
@@ -1706,7 +1708,7 @@ quic_get_1rtt_hp_cipher(packet_info *pinfo, quic_info_data_t *quic_info, gboolea
return NULL;
}
- // Create initial cipher handles for KEY_PHASE 0 using the 1-RTT keys.
+ // Create initial cipher handles for Key Phase 0 using the 1-RTT keys.
if (!quic_cipher_prepare(&client_pp->cipher[0], quic_info->hash_algo,
quic_info->cipher_algo, quic_info->cipher_mode, client_pp->next_secret, &error) ||
!quic_cipher_prepare(&server_pp->cipher[0], quic_info->hash_algo,
@@ -1715,8 +1717,8 @@ quic_get_1rtt_hp_cipher(packet_info *pinfo, quic_info_data_t *quic_info, gboolea
return NULL;
}
// Rotate the 1-RTT key for the client and server for the next key update.
- quic_update_key(quic_info->hash_algo, client_pp);
- quic_update_key(quic_info->hash_algo, server_pp);
+ quic_update_key(quic_info->version, quic_info->hash_algo, client_pp);
+ quic_update_key(quic_info->version, quic_info->hash_algo, server_pp);
}
// Note: Header Protect cipher does not change after Key Update.
@@ -1767,7 +1769,7 @@ quic_get_pp_cipher(gboolean key_phase, quic_info_data_t *quic_info, gboolean fro
/* Verified the cipher, use it from now on and rotate the key. */
quic_cipher_reset(&pp_state->cipher[key_phase]);
pp_state->cipher[key_phase] = new_cipher;
- quic_update_key(quic_info->hash_algo, pp_state);
+ quic_update_key(quic_info->version, quic_info->hash_algo, pp_state);
pp_state->key_phase = key_phase;
//pp_state->changed_in_pkn = pkn;