Coverage Report

Created: 2026-03-01 06:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ndpi/src/lib/protocols/quic.c
Line
Count
Source
1
/*
2
 * quic.c
3
 *
4
 * Copyright (C) 2012-22 - ntop.org
5
 *
6
 * This module is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Lesser General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This module is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public License.
17
 * If not, see <http://www.gnu.org/licenses/>.
18
 *
19
 */
20
21
#if defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__
22
#include <sys/endian.h>
23
#endif
24
25
#include "ndpi_protocol_ids.h"
26
#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_QUIC
27
#include "ndpi_api.h"
28
#include "ndpi_private.h"
29
30
31
#ifdef USE_HOST_LIBGCRYPT
32
#include <gcrypt.h>
33
#else
34
#include <gcrypt_light.h>
35
#endif
36
37
/* This dissector handles GQUIC and IETF-QUIC both.
38
   Main references:
39
   * https://groups.google.com/a/chromium.org/g/proto-quic/c/wVHBir-uRU0?pli=1
40
   * https://groups.google.com/a/chromium.org/g/proto-quic/c/OAVgFqw2fko/m/jCbjP0AVAAAJ
41
   * https://groups.google.com/a/chromium.org/g/proto-quic/c/OAVgFqw2fko/m/-NYxlh88AgAJ
42
   * https://docs.google.com/document/d/1FcpCJGTDEMblAs-Bm5TYuqhHyUqeWpqrItw2vkMFsdY/edit
43
   * https://www.rfc-editor.org/rfc/rfc9001.txt [Using TLS over QUIC]
44
   * https://www.rfc-editor.org/rfc/rfc9000.txt [v1]
45
   * https://www.rfc-editor.org/rfc/rfc9369.txt [v2]
46
   */
47
48
/* Versions */
49
0
#define V_2   0x6b3343cf
50
0
#define V_1   0x00000001
51
0
#define V_Q024    0x51303234
52
0
#define V_Q025    0x51303235
53
0
#define V_Q030    0x51303330
54
0
#define V_Q033    0x51303333
55
0
#define V_Q034    0x51303334
56
0
#define V_Q035    0x51303335
57
0
#define V_Q037    0x51303337
58
0
#define V_Q039    0x51303339
59
0
#define V_Q043    0x51303433
60
0
#define V_Q046    0x51303436
61
0
#define V_Q050    0x51303530
62
0
#define V_T050    0x54303530
63
0
#define V_T051    0x54303531
64
0
#define V_MVFST_22  0xfaceb001
65
0
#define V_MVFST_27  0xfaceb002
66
0
#define V_MVFST_EXP 0xfaceb00e
67
68
0
#define QUIC_MAX_CID_LENGTH  20
69
70
static int is_version_forcing_vn(uint32_t version)
71
0
{
72
0
  return (version & 0x0F0F0F0F) == 0x0a0a0a0a; /* Forcing Version Negotiation */
73
0
}
74
static int is_version_gquic(uint32_t version)
75
0
{
76
0
  return ((version & 0xFFFFFF00) == 0x54303500) /* T05X */ ||
77
0
    ((version & 0xFFFFFF00) == 0x51303500) /* Q05X */ ||
78
0
    ((version & 0xFFFFFF00) == 0x51303400) /* Q04X */ ||
79
0
    ((version & 0xFFFFFF00) == 0x51303300) /* Q03X */ ||
80
0
    ((version & 0xFFFFFF00) == 0x51303200) /* Q02X */;
81
0
}
82
static int is_version_quic(uint32_t version)
83
0
{
84
0
  return version == V_1 ||
85
0
    ((version & 0xFFFFFF00) == 0xFF000000) /* IETF Drafts*/ ||
86
0
    ((version & 0xFFFFF000) == 0xfaceb000) /* Facebook */ ||
87
0
    is_version_forcing_vn(version) ||
88
0
    (version == V_2);
89
0
}
90
static int is_version_valid(uint32_t version)
91
0
{
92
0
  return is_version_gquic(version) || is_version_quic(version);
93
0
}
94
static uint8_t get_u8_quic_ver(uint32_t version)
95
0
{
96
  /* IETF Draft versions */
97
0
  if((version >> 8) == 0xff0000)
98
0
    return (uint8_t)version;
99
  /* QUIC (final?) constants for v1 are defined in draft-33, but latest
100
     draft version is -34 */
101
0
  if (version == 0x00000001) {
102
0
    return 34;
103
0
  }
104
105
0
  if (version == V_MVFST_22)
106
0
    return 22;
107
0
  if (version == V_MVFST_27 || version == V_MVFST_EXP)
108
0
    return 27;
109
110
  /* "Versions that follow the pattern 0x?a?a?a?a are reserved for use in
111
     forcing version negotiation to be exercised".
112
     We can't return a correct draft version because we don't have a real
113
     version here! That means that we can't decode any data and we can dissect
114
     only the cleartext header.
115
     Let's return v1 (any other numbers should be fine, anyway) to only allow
116
     the dissection of the (expected) long header */
117
0
  if(is_version_forcing_vn(version))
118
0
    return 34;
119
120
  /* QUIC Version 2 */
121
0
  if (version == V_2)
122
0
    return 100;
123
124
0
  return 0;
125
0
}
126
127
static int is_quic_ver_less_than(uint32_t version, uint8_t max_version)
128
0
{
129
0
  uint8_t u8_ver = get_u8_quic_ver(version);
130
0
  return u8_ver && u8_ver <= max_version;
131
0
}
132
int is_quic_ver_greater_than(uint32_t version, uint8_t min_version)
133
0
{
134
0
  return get_u8_quic_ver(version) >= min_version;
135
0
}
136
static uint8_t get_u8_gquic_ver(uint32_t version)
137
0
{
138
0
  if(is_version_gquic(version)) {
139
0
    version = ntohl(((uint16_t)version) << 16);
140
0
    return atoi((char *)&version);
141
0
  }
142
0
  return 0;
143
0
}
144
static int is_gquic_ver_less_than(uint32_t version, uint8_t max_version)
145
0
{
146
0
  uint8_t u8_ver = get_u8_gquic_ver(version);
147
0
  return u8_ver && u8_ver <= max_version;
148
0
}
149
static int is_version_supported(uint32_t version)
150
0
{
151
0
  return (version == V_Q024 ||
152
0
          version == V_Q025 ||
153
0
          version == V_Q030 ||
154
0
          version == V_Q033 ||
155
0
          version == V_Q034 ||
156
0
          version == V_Q035 ||
157
0
          version == V_Q037 ||
158
0
          version == V_Q039 ||
159
0
          version == V_Q043 ||
160
0
          version == V_Q046 ||
161
0
          version == V_Q050 ||
162
0
          version == V_T050 ||
163
0
          version == V_T051 ||
164
0
    version == V_MVFST_22 ||
165
0
    version == V_MVFST_27 ||
166
0
    version == V_MVFST_EXP ||
167
0
          is_quic_ver_greater_than(version, 23));
168
0
}
169
static int is_version_with_encrypted_header(uint32_t version)
170
0
{
171
0
  return is_version_quic(version) ||
172
0
    ((version & 0xFFFFFF00) == 0x51303500) /* Q05X */ ||
173
0
    ((version & 0xFFFFFF00) == 0x54303500) /* T05X */;
174
0
}
175
int is_version_with_tls(uint32_t version)
176
0
{
177
0
  return is_version_quic(version) ||
178
0
    ((version & 0xFFFFFF00) == 0x54303500) /* T05X */;
179
0
}
180
int is_version_with_var_int_transport_params(uint32_t version)
181
0
{
182
0
  return (is_version_quic(version) && is_quic_ver_greater_than(version, 27)) ||
183
0
    (version == V_T051);
184
0
}
185
int is_version_with_ietf_long_header(uint32_t version)
186
0
{
187
  /* At least draft-ietf-quic-invariants-06, or newer*/
188
0
  return is_version_quic(version) ||
189
0
    ((version & 0xFFFFFF00) == 0x51303500) /* Q05X */ ||
190
0
    ((version & 0xFFFFFF00) == 0x54303500) /* T05X */;
191
0
}
192
static int is_version_with_v1_labels(uint32_t version)
193
0
{
194
0
  if(((version & 0xFFFFFF00) == 0x51303500)  /* Q05X */ ||
195
0
     ((version & 0xFFFFFF00) == 0x54303500)) /* T05X */
196
0
    return 1;
197
0
  return is_quic_ver_less_than(version, 34);
198
0
}
199
static int is_version_quic_v2(uint32_t version)
200
0
{
201
0
  return version == V_2;
202
0
}
203
204
0
char *ndpi_quic_version2str(char *buf, int buf_len, u_int32_t version) {
205
206
0
  if(buf == NULL || buf_len <= 1)
207
0
    return NULL;
208
209
0
  switch(version) {
210
0
  case V_2: strncpy(buf, "V-2", buf_len); buf[buf_len - 1] = '\0'; return buf;
211
0
  case V_1: strncpy(buf, "V-1", buf_len); buf[buf_len - 1] = '\0'; return buf;
212
0
  case V_Q024: strncpy(buf, "Q024", buf_len); buf[buf_len - 1] = '\0'; return buf;
213
0
  case V_Q025: strncpy(buf, "Q025", buf_len); buf[buf_len - 1] = '\0'; return buf;
214
0
  case V_Q030: strncpy(buf, "Q030", buf_len); buf[buf_len - 1] = '\0'; return buf;
215
0
  case V_Q033: strncpy(buf, "Q033", buf_len); buf[buf_len - 1] = '\0'; return buf;
216
0
  case V_Q034: strncpy(buf, "Q034", buf_len); buf[buf_len - 1] = '\0'; return buf;
217
0
  case V_Q035: strncpy(buf, "Q035", buf_len); buf[buf_len - 1] = '\0'; return buf;
218
0
  case V_Q037: strncpy(buf, "Q037", buf_len); buf[buf_len - 1] = '\0'; return buf;
219
0
  case V_Q039: strncpy(buf, "Q039", buf_len); buf[buf_len - 1] = '\0'; return buf;
220
0
  case V_Q043: strncpy(buf, "Q043", buf_len); buf[buf_len - 1] = '\0'; return buf;
221
0
  case V_Q046: strncpy(buf, "Q046", buf_len); buf[buf_len - 1] = '\0'; return buf;
222
0
  case V_Q050: strncpy(buf, "Q050", buf_len); buf[buf_len - 1] = '\0'; return buf;
223
0
  case V_T050: strncpy(buf, "T050", buf_len); buf[buf_len - 1] = '\0'; return buf;
224
0
  case V_T051: strncpy(buf, "T051", buf_len); buf[buf_len - 1] = '\0'; return buf;
225
0
  case V_MVFST_22: strncpy(buf, "MVFST-22", buf_len); buf[buf_len - 1] = '\0'; return buf;
226
0
  case V_MVFST_27: strncpy(buf, "MVFST-27", buf_len); buf[buf_len - 1] = '\0'; return buf;
227
0
  case V_MVFST_EXP: strncpy(buf, "MVFST-EXP", buf_len); buf[buf_len - 1] = '\0'; return buf;
228
0
  }
229
230
0
  if(is_version_forcing_vn(version)) {
231
0
    strncpy(buf, "Ver-Negotiation", buf_len);
232
0
    buf[buf_len - 1] = '\0';
233
0
    return buf;
234
0
  }
235
0
  if(((version & 0xFFFFFF00) == 0xFF000000)) {
236
0
    snprintf(buf, buf_len, "Draft-%d", version & 0x000000FF);
237
0
    buf[buf_len - 1] = '\0';
238
0
    return buf;
239
0
  }
240
241
0
  ndpi_snprintf(buf, buf_len, "Unknown (%04X)", version);
242
0
  return buf;
243
0
}
244
245
int quic_len(const uint8_t *buf, uint64_t *value)
246
0
{
247
0
  *value = buf[0];
248
0
  switch((*value) >> 6) {
249
0
  case 0:
250
0
    (*value) &= 0x3F;
251
0
    return 1;
252
0
  case 1:
253
0
    *value = ntohs(*(uint16_t *)buf) & 0x3FFF;
254
0
    return 2;
255
0
  case 2:
256
0
    *value = ntohl(*(uint32_t *)buf) & 0x3FFFFFFF;
257
0
    return 4;
258
0
  case 3:
259
0
    *value = ndpi_ntohll(get_u_int64_t(buf, 0)) & 0x3FFFFFFFFFFFFFFF;
260
0
    return 8;
261
0
  default: /* No Possible */
262
0
    return 0;
263
0
  }
264
0
}
265
int quic_len_buffer_still_required(uint8_t value)
266
0
{
267
0
  switch(value >> 6) {
268
0
  case 0:
269
0
    return 0;
270
0
  case 1:
271
0
    return 1;
272
0
  case 2:
273
0
    return 3;
274
0
  case 3:
275
0
    return 7;
276
0
  default: /* No Possible */
277
0
    return 0;
278
0
  }
279
0
}
280
281
282
static uint16_t gquic_get_u16(const uint8_t *buf, uint32_t version)
283
0
{
284
0
  if(version >= V_Q039)
285
0
    return ntohs(*(uint16_t *)buf);
286
0
  return le16toh(*(uint16_t *)buf);
287
0
}
288
289
290
#ifdef NDPI_ENABLE_DEBUG_MESSAGES
291
static char *__gcry_err(gpg_error_t err, char *buf, size_t buflen)
292
{
293
  gpg_strerror_r(err, buf, buflen);
294
  /* I am not sure if the string will be always null-terminated...
295
     Better safe than sorry */
296
  if(buflen > 0)
297
    buf[buflen - 1] = '\0';
298
  return buf;
299
}
300
#endif
301
302
static uint64_t pntoh64(const void *p)
303
0
{
304
0
  return (uint64_t)*((const uint8_t *)(p)+0)<<56|
305
0
    (uint64_t)*((const uint8_t *)(p)+1)<<48|
306
0
    (uint64_t)*((const uint8_t *)(p)+2)<<40|
307
0
    (uint64_t)*((const uint8_t *)(p)+3)<<32|
308
0
    (uint64_t)*((const uint8_t *)(p)+4)<<24|
309
0
    (uint64_t)*((const uint8_t *)(p)+5)<<16|
310
0
    (uint64_t)*((const uint8_t *)(p)+6)<<8|
311
0
    (uint64_t)*((const uint8_t *)(p)+7)<<0;
312
0
}
313
static void phton64(uint8_t *p, uint64_t v)
314
0
{
315
0
  p[0] = (uint8_t)(v >> 56);
316
0
  p[1] = (uint8_t)(v >> 48);
317
0
  p[2] = (uint8_t)(v >> 40);
318
0
  p[3] = (uint8_t)(v >> 32);
319
0
  p[4] = (uint8_t)(v >> 24);
320
0
  p[5] = (uint8_t)(v >> 16);
321
0
  p[6] = (uint8_t)(v >> 8);
322
0
  p[7] = (uint8_t)(v >> 0);
323
0
}
324
325
static void *memdup(const uint8_t *orig, size_t len)
326
0
{
327
0
  void *dest = ndpi_malloc(len);
328
0
  if(dest)
329
0
    memcpy(dest, orig, len);
330
0
  return dest;
331
0
}
332
333
334
/*
335
 * Generic Wireshark definitions
336
 */
337
338
0
#define HASH_SHA2_256_LENGTH    32
339
0
#define TLS13_AEAD_NONCE_LENGTH   12
340
341
typedef struct _StringInfo {
342
  unsigned char *data;    /* Backing storage which may be larger than data_len */
343
  unsigned int data_len;  /* Length of the meaningful part of data */
344
} StringInfo;
345
346
/* QUIC decryption context. */
347
348
typedef struct quic_hp_cipher {
349
  gcry_cipher_hd_t hp_cipher;  /* Header protection cipher. */
350
} quic_hp_cipher;
351
typedef struct quic_pp_cipher {
352
  gcry_cipher_hd_t pp_cipher;  /* Packet protection cipher. */
353
  uint8_t pp_iv[TLS13_AEAD_NONCE_LENGTH];
354
} quic_pp_cipher;
355
typedef struct quic_ciphers {
356
  quic_hp_cipher hp_cipher;
357
  quic_pp_cipher pp_cipher;
358
} quic_ciphers;
359
360
typedef struct quic_decrypt_result {
361
  uint8_t *data; /* Decrypted result on success (file-scoped). */
362
  uint32_t data_len;   /* Size of decrypted data. */
363
} quic_decrypt_result_t;
364
365
366
/*
367
 * From wsutil/wsgcrypt.{c,h}
368
 */
369
370
static gcry_error_t ws_hmac_buffer(int algo, void *digest, const void *buffer,
371
           size_t length, const void *key, size_t keylen)
372
0
{
373
0
  gcry_md_hd_t hmac_handle;
374
0
  gcry_error_t result = gcry_md_open(&hmac_handle, algo, GCRY_MD_FLAG_HMAC);
375
0
  if(result) {
376
0
    return result;
377
0
  }
378
0
  result = gcry_md_setkey(hmac_handle, key, keylen);
379
0
  if(result) {
380
0
    gcry_md_close(hmac_handle);
381
0
    return result;
382
0
  }
383
0
  gcry_md_write(hmac_handle, buffer, length);
384
0
  memcpy(digest, gcry_md_read(hmac_handle, 0), gcry_md_get_algo_dlen(algo));
385
0
  gcry_md_close(hmac_handle);
386
0
  return GPG_ERR_NO_ERROR;
387
0
}
388
static gcry_error_t hkdf_expand(int hashalgo, const uint8_t *prk, uint32_t prk_len,
389
        const uint8_t *info, uint32_t info_len,
390
        uint8_t *out, uint32_t out_len)
391
0
{
392
  /* Current maximum hash output size: 48 bytes for SHA-384. */
393
0
  uint8_t lastoutput[48];
394
0
  gcry_md_hd_t h;
395
0
  gcry_error_t err;
396
0
  const unsigned int hash_len = gcry_md_get_algo_dlen(hashalgo);
397
0
  uint32_t offset;
398
399
  /* Some sanity checks */
400
0
  if(!(out_len > 0 && out_len <= 255 * hash_len) ||
401
0
     !(hash_len > 0 && hash_len <= sizeof(lastoutput))) {
402
0
    return GPG_ERR_INV_ARG;
403
0
  }
404
405
0
  err = gcry_md_open(&h, hashalgo, GCRY_MD_FLAG_HMAC);
406
0
  if(err) {
407
0
    return err;
408
0
  }
409
410
0
  for(offset = 0; offset < out_len; offset += hash_len) {
411
0
    gcry_md_reset(h);
412
0
    gcry_md_setkey(h, prk, prk_len); /* Set PRK */
413
0
    if(offset > 0) {
414
0
      gcry_md_write(h, lastoutput, hash_len); /* T(1..N) */
415
0
    }
416
0
    gcry_md_write(h, info, info_len);                   /* info */
417
418
0
    uint8_t c = offset / hash_len + 1;
419
0
    gcry_md_write(h, &c, sizeof(c));                    /* constant 0x01..N */
420
421
0
    memcpy(lastoutput, gcry_md_read(h, hashalgo), hash_len);
422
0
    memcpy(out + offset, lastoutput, ndpi_min(hash_len, out_len - offset));
423
0
  }
424
425
0
  gcry_md_close(h);
426
0
  return 0;
427
0
}
428
/*
429
 * Calculate HKDF-Extract(salt, IKM) -> PRK according to RFC 5869.
430
 * Caller MUST ensure that 'prk' is large enough to store the digest from hash
431
 * algorithm 'hashalgo' (e.g. 32 bytes for SHA-256).
432
 */
433
static gcry_error_t hkdf_extract(int hashalgo, const uint8_t *salt, size_t salt_len,
434
         const uint8_t *ikm, size_t ikm_len, uint8_t *prk)
435
0
{
436
  /* PRK = HMAC-Hash(salt, IKM) where salt is key, and IKM is input. */
437
0
  return ws_hmac_buffer(hashalgo, prk, ikm, ikm_len, salt, salt_len);
438
0
}
439
440
441
/*
442
 * From epan/dissectors/packet-tls-utils.c
443
 */
444
445
/*
446
 * Computes HKDF-Expand-Label(Secret, Label, Hash(context_value), Length) with a
447
 * custom label prefix. If "context_hash" is NULL, then an empty context is
448
 * used. Otherwise it must have the same length as the hash algorithm output.
449
 */
450
static int tls13_hkdf_expand_label_context(struct ndpi_detection_module_struct *ndpi_struct,
451
             int md, const StringInfo *secret,
452
             const char *label_prefix, const char *label,
453
             const uint8_t *context_hash, uint8_t context_length,
454
             uint16_t out_len, uint8_t **out)
455
0
{
456
  /* RFC 8446 Section 7.1:
457
   * HKDF-Expand-Label(Secret, Label, Context, Length) =
458
   *      HKDF-Expand(Secret, HkdfLabel, Length)
459
   * struct {
460
   *     uint16 length = Length;
461
   *     opaque label<7..255> = "tls13 " + Label; // "tls13 " is label prefix.
462
   *     opaque context<0..255> = Context;
463
   * } HkdfLabel;
464
   *
465
   * RFC 5869 HMAC-based Extract-and-Expand Key Derivation Function (HKDF):
466
   * HKDF-Expand(PRK, info, L) -> OKM
467
   */
468
0
  gcry_error_t err;
469
0
  const unsigned int label_prefix_length = (unsigned int)strlen(label_prefix);
470
0
  const unsigned label_length = (unsigned int)strlen(label);
471
#ifdef NDPI_ENABLE_DEBUG_MESSAGES
472
  char buferr[128];
473
#endif
474
475
  /* Some sanity checks */
476
0
  if(!(label_length > 0 && label_prefix_length + label_length <= 255)) {
477
0
    NDPI_LOG_DBG(ndpi_struct, "Failed sanity checks\n");
478
0
    return 0;
479
0
  }
480
481
  /* info = HkdfLabel { length, label, context } */
482
  /* Keep original Wireshark code as reference */
483
#if 0
484
  GByteArray *info = g_byte_array_new();
485
  const uint16_t length = htons(out_len);
486
  g_byte_array_append(info, (const guint8 *)&length, sizeof(length));
487
488
  const uint8_t label_vector_length = label_prefix_length + label_length;
489
  g_byte_array_append(info, &label_vector_length, 1);
490
  g_byte_array_append(info, (const uint8_t *)label_prefix, label_prefix_length);
491
  g_byte_array_append(info, (const uint8_t *)label, label_length);
492
493
  g_byte_array_append(info, &context_length, 1);
494
  if (context_length) {
495
    g_byte_array_append(info, context_hash, context_length);
496
  }
497
#else
498
0
  uint32_t info_len = 0;
499
0
  uint8_t *info_data = (uint8_t *)ndpi_malloc(1024);
500
0
  if(!info_data)
501
0
    return 0;
502
0
  const uint16_t length = htons(out_len);
503
0
  memcpy(&info_data[info_len], &length, sizeof(length));
504
0
  info_len += sizeof(length);
505
506
0
  const uint8_t label_vector_length = label_prefix_length + label_length;
507
0
  memcpy(&info_data[info_len], &label_vector_length, 1);
508
0
  info_len += 1;
509
0
  memcpy(&info_data[info_len], (const uint8_t *)label_prefix, label_prefix_length);
510
0
  info_len += label_prefix_length;
511
0
  memcpy(&info_data[info_len], (const uint8_t *)label, label_length);
512
0
  info_len += label_length;
513
514
0
  memcpy(&info_data[info_len], &context_length, 1);
515
0
  info_len += 1;
516
0
  if(context_length && context_hash != NULL) {
517
0
    memcpy(&info_data[info_len], context_hash, context_length);
518
0
    info_len += context_length;
519
0
  }
520
0
#endif
521
522
0
  *out = (uint8_t *)ndpi_malloc(out_len);
523
0
  if(!*out) {
524
0
    ndpi_free(info_data);
525
0
    return 0;
526
0
  }
527
0
  err = hkdf_expand(md, secret->data, secret->data_len, info_data, info_len, *out, out_len);
528
0
  ndpi_free(info_data);
529
530
0
  if(err) {
531
0
    NDPI_LOG_DBG(ndpi_struct, "Failed hkdf_expand: %s\n", __gcry_err(err, buferr, sizeof(buferr)));
532
0
    ndpi_free(*out);
533
0
    *out = NULL;
534
0
    return 0;
535
0
  }
536
537
0
  return 1;
538
0
}
539
static int tls13_hkdf_expand_label(struct ndpi_detection_module_struct *ndpi_struct,
540
           int md, const StringInfo *secret,
541
           const char *label_prefix, const char *label,
542
           uint16_t out_len, unsigned char **out)
543
0
{
544
0
  return tls13_hkdf_expand_label_context(ndpi_struct, md, secret, label_prefix, label, NULL, 0, out_len, out);
545
0
}
546
547
548
/*
549
 * From epan/dissectors/packet-quic.c
550
 */
551
552
static int quic_hkdf_expand_label(struct ndpi_detection_module_struct *ndpi_struct,
553
          int hash_algo, uint8_t *secret, uint32_t secret_len,
554
          const char *label, uint8_t *out, uint32_t out_len)
555
0
{
556
0
  const StringInfo secret_si = { secret, secret_len };
557
0
  uint8_t *out_mem = NULL;
558
0
  if(tls13_hkdf_expand_label(ndpi_struct, hash_algo, &secret_si, "tls13 ", label, out_len, &out_mem)) {
559
0
    memcpy(out, out_mem, out_len);
560
0
    ndpi_free(out_mem);
561
0
    return 1;
562
0
  }
563
0
  return 0;
564
0
}
565
static void quic_hp_cipher_reset(quic_hp_cipher *hp_cipher)
566
0
{
567
0
  gcry_cipher_close(hp_cipher->hp_cipher);
568
#if 0
569
  memset(hp_cipher, 0, sizeof(*hp_cipher));
570
#endif
571
0
}
572
static void quic_pp_cipher_reset(quic_pp_cipher *pp_cipher)
573
0
{
574
0
  gcry_cipher_close(pp_cipher->pp_cipher);
575
#if 0
576
  memset(pp_cipher, 0, sizeof(*pp_cipher));
577
#endif
578
0
}
579
static void quic_ciphers_reset(quic_ciphers *ciphers)
580
0
{
581
0
  quic_hp_cipher_reset(&ciphers->hp_cipher);
582
0
  quic_pp_cipher_reset(&ciphers->pp_cipher);
583
0
}
584
/**
585
 * Expands the secret (length MUST be the same as the "hash_algo" digest size)
586
 * and initialize cipher with the new key.
587
 */
588
static int quic_hp_cipher_init(struct ndpi_detection_module_struct *ndpi_struct,
589
             quic_hp_cipher *hp_cipher, int hash_algo,
590
             uint8_t key_length, uint8_t *secret,
591
             uint32_t version)
592
0
{
593
0
  uint8_t hp_key[256/8]; /* Maximum key size is for AES256 cipher. */
594
0
  uint32_t hash_len = gcry_md_get_algo_dlen(hash_algo);
595
0
  char const * const label = is_version_with_v1_labels(version) ? "quic hp" : "quicv2 hp";
596
597
0
  if(!quic_hkdf_expand_label(ndpi_struct, hash_algo, secret, hash_len, label, hp_key, key_length)) {
598
0
    return 0;
599
0
  }
600
601
0
  return gcry_cipher_setkey(hp_cipher->hp_cipher, hp_key, key_length) == 0;
602
0
}
603
static int quic_pp_cipher_init(struct ndpi_detection_module_struct *ndpi_struct,
604
             quic_pp_cipher *pp_cipher, int hash_algo,
605
             uint8_t key_length, uint8_t *secret,
606
             uint32_t version)
607
0
{
608
0
  uint8_t write_key[256/8]; /* Maximum key size is for AES256 cipher. */
609
0
  uint32_t hash_len = gcry_md_get_algo_dlen(hash_algo);
610
0
  char const * const key_label = is_version_with_v1_labels(version) ? "quic key" : "quicv2 key";
611
0
  char const * const iv_label = is_version_with_v1_labels(version) ? "quic iv" : "quicv2 iv";
612
613
0
  if(key_length > sizeof(write_key)) {
614
0
    return 0;
615
0
  }
616
617
0
  if(!quic_hkdf_expand_label(ndpi_struct, hash_algo, secret, hash_len, key_label, write_key, key_length) ||
618
0
     !quic_hkdf_expand_label(ndpi_struct, hash_algo, secret, hash_len, iv_label, pp_cipher->pp_iv, sizeof(pp_cipher->pp_iv))) {
619
0
    return 0;
620
0
  }
621
622
0
  return gcry_cipher_setkey(pp_cipher->pp_cipher, write_key, key_length) == 0;
623
0
}
624
/**
625
 * Maps a Packet Protection cipher to the Packet Number protection cipher.
626
 * See https://tools.ietf.org/html/draft-ietf-quic-tls-22#section-5.4.3
627
 */
628
static int quic_get_pn_cipher_algo(int cipher_algo, int *hp_cipher_mode)
629
0
{
630
0
  switch (cipher_algo) {
631
0
  case GCRY_CIPHER_AES128:
632
0
  case GCRY_CIPHER_AES256:
633
0
    *hp_cipher_mode = GCRY_CIPHER_MODE_ECB;
634
0
    return 1;
635
0
  default:
636
0
    return 0;
637
0
  }
638
0
}
639
/*
640
 * (Re)initialize the PNE/PP ciphers using the given cipher algorithm.
641
 * If the optional base secret is given, then its length MUST match the hash
642
 * algorithm output.
643
 */
644
static int quic_hp_cipher_prepare(struct ndpi_detection_module_struct *ndpi_struct,
645
                                  quic_hp_cipher *hp_cipher, int hash_algo, int cipher_algo,
646
                                  uint8_t *secret, u_int32_t version)
647
0
{
648
#if 0
649
  /* Clear previous state (if any). */
650
  quic_hp_cipher_reset(hp_cipher);
651
#endif
652
653
0
  int hp_cipher_mode;
654
0
  if(!quic_get_pn_cipher_algo(cipher_algo, &hp_cipher_mode)) {
655
0
    NDPI_LOG_DBG(ndpi_struct, "Unsupported cipher algorithm\n");
656
0
    return 0;
657
0
  }
658
659
0
  if(gcry_cipher_open(&hp_cipher->hp_cipher, cipher_algo, hp_cipher_mode, 0)) {
660
0
    quic_hp_cipher_reset(hp_cipher);
661
0
    NDPI_LOG_DBG(ndpi_struct, "Failed to create HP cipher\n");
662
0
    return 0;
663
0
  }
664
665
0
  if(secret) {
666
0
    uint32_t cipher_keylen = (uint8_t)gcry_cipher_get_algo_keylen(cipher_algo);
667
0
    if(!quic_hp_cipher_init(ndpi_struct, hp_cipher, hash_algo, cipher_keylen, secret, version)) {
668
0
      quic_hp_cipher_reset(hp_cipher);
669
0
      NDPI_LOG_DBG(ndpi_struct, "Failed to derive key material for HP cipher\n");
670
0
      return 0;
671
0
    }
672
0
  }
673
674
0
  return 1;
675
0
}
676
static int quic_pp_cipher_prepare(struct ndpi_detection_module_struct *ndpi_struct,
677
                                  quic_pp_cipher *pp_cipher, int hash_algo, int cipher_algo,
678
                                  int cipher_mode, uint8_t *secret, u_int32_t version)
679
0
{
680
#if 0
681
  /* Clear previous state (if any). */
682
  quic_pp_cipher_reset(pp_cipher);
683
#endif
684
685
0
  if(gcry_cipher_open(&pp_cipher->pp_cipher, cipher_algo, cipher_mode, 0)) {
686
0
    quic_pp_cipher_reset(pp_cipher);
687
0
    NDPI_LOG_DBG(ndpi_struct, "Failed to create PP cipher\n");
688
0
    return 0;
689
0
  }
690
691
0
  if(secret) {
692
0
    uint32_t cipher_keylen = (uint8_t)gcry_cipher_get_algo_keylen(cipher_algo);
693
0
    if(!quic_pp_cipher_init(ndpi_struct, pp_cipher, hash_algo, cipher_keylen, secret, version)) {
694
0
      quic_pp_cipher_reset(pp_cipher);
695
0
      NDPI_LOG_DBG(ndpi_struct, "Failed to derive key material for PP cipher\n");
696
0
      return 0;
697
0
    }
698
0
  }
699
700
0
  return 1;
701
0
}
702
static int quic_ciphers_prepare(struct ndpi_detection_module_struct *ndpi_struct,
703
                                quic_ciphers *ciphers, int hash_algo, int cipher_algo,
704
                                int cipher_mode, uint8_t *secret, u_int32_t version)
705
0
{
706
0
  int ret;
707
708
0
  ret = quic_hp_cipher_prepare(ndpi_struct, &ciphers->hp_cipher, hash_algo, cipher_algo, secret, version);
709
0
  if(ret != 1)
710
0
    return ret;
711
0
  ret = quic_pp_cipher_prepare(ndpi_struct, &ciphers->pp_cipher, hash_algo, cipher_algo, cipher_mode, secret, version);
712
0
  if(ret != 1)
713
0
    quic_hp_cipher_reset(&ciphers->hp_cipher);
714
0
  return ret;
715
0
}
716
/**
717
 * Given a header protection cipher, a buffer and the packet number offset,
718
 * return the unmasked first byte and packet number.
719
 * If the loss bits feature is enabled, the protected bits in the first byte
720
 * are fewer than usual: 3 instead of 5 (on short headers only)
721
 */
722
static int quic_decrypt_header(const uint8_t *packet_payload,
723
             uint32_t pn_offset, quic_hp_cipher *hp_cipher,
724
             int hp_cipher_algo, uint8_t *first_byte, uint32_t *pn,
725
             int loss_bits_negotiated)
726
0
{
727
0
  if(!hp_cipher->hp_cipher) {
728
    /* Need to know the cipher */
729
0
    return 0;
730
0
  }
731
0
  gcry_cipher_hd_t h = hp_cipher->hp_cipher;
732
733
  /* Sample is always 16 bytes and starts after PKN (assuming length 4).
734
     https://tools.ietf.org/html/draft-ietf-quic-tls-22#section-5.4.2 */
735
0
  uint8_t sample[16];
736
0
  memcpy(sample, packet_payload + pn_offset + 4, 16);
737
738
0
  uint8_t mask[5] = { 0 };
739
0
  switch (hp_cipher_algo) {
740
0
  case GCRY_CIPHER_AES128:
741
0
  case GCRY_CIPHER_AES256:
742
    /* Encrypt in-place with AES-ECB and extract the mask. */
743
0
    if(gcry_cipher_encrypt(h, sample, sizeof(sample), NULL, 0)) {
744
0
      return 0;
745
0
    }
746
0
    memcpy(mask, sample, sizeof(mask));
747
0
    break;
748
0
  default:
749
0
    return 0;
750
0
  }
751
752
  /* https://tools.ietf.org/html/draft-ietf-quic-tls-22#section-5.4.1 */
753
0
  uint8_t packet0 = packet_payload[0];
754
0
  if((packet0 & 0x80) == 0x80) {
755
    /* Long header: 4 bits masked */
756
0
    packet0 ^= mask[0] & 0x0f;
757
0
  } else {
758
    /* Short header */
759
0
    if(loss_bits_negotiated == 0) {
760
      /* Standard mask: 5 bits masked */
761
0
      packet0 ^= mask[0] & 0x1F;
762
0
    } else {
763
      /* https://tools.ietf.org/html/draft-ferrieuxhamchaoui-quic-lossbits-03#section-5.3 */
764
0
      packet0 ^= mask[0] & 0x07;
765
0
    }
766
0
  }
767
0
  uint32_t pkn_len = (packet0 & 0x03) + 1;
768
  /* printf("packet0 0x%x pkn_len %d\n", packet0, pkn_len); */
769
770
0
  uint8_t pkn_bytes[4];
771
0
  memcpy(pkn_bytes, packet_payload + pn_offset, pkn_len);
772
0
  uint32_t pkt_pkn = 0, i;
773
0
  for(i = 0; i < pkn_len; i++) {
774
0
    pkt_pkn |= (uint32_t)(pkn_bytes[i] ^ mask[1 + i]) << (8 * (pkn_len - 1 - i));
775
0
  }
776
0
  *first_byte = packet0;
777
0
  *pn = pkt_pkn;
778
0
  return 1;
779
0
}
780
/**
781
 * Given a QUIC message (header + non-empty payload), the actual packet number,
782
 * try to decrypt it using the cipher.
783
 * As the header points to the original buffer with an encrypted packet number,
784
 * the (encrypted) packet number length is also included.
785
 *
786
 * The actual packet number must be constructed according to
787
 * https://tools.ietf.org/html/draft-ietf-quic-transport-22#section-12.3
788
 */
789
static void quic_decrypt_message(struct ndpi_detection_module_struct *ndpi_struct,
790
         quic_pp_cipher *pp_cipher, const uint8_t *packet_payload, uint32_t packet_payload_len,
791
         uint32_t header_length, uint8_t first_byte, uint32_t pkn_len,
792
         uint64_t packet_number, quic_decrypt_result_t *result)
793
0
{
794
0
  gcry_error_t err;
795
0
  uint8_t *header;
796
0
  uint8_t nonce[TLS13_AEAD_NONCE_LENGTH];
797
0
  uint8_t *buffer;
798
0
  uint8_t atag[16];
799
0
  uint32_t buffer_length, i;
800
#ifdef NDPI_ENABLE_DEBUG_MESSAGES
801
  char buferr[128];
802
#endif
803
804
0
  if(!(pp_cipher != NULL) ||
805
0
     !(pp_cipher->pp_cipher != NULL) ||
806
0
     !(pkn_len < header_length) ||
807
0
     !(1 <= pkn_len && pkn_len <= 4)) {
808
0
    NDPI_LOG_DBG(ndpi_struct, "Failed sanity checks\n");
809
0
    return;
810
0
  }
811
  /* Copy header, but replace encrypted first byte and PKN by plaintext. */
812
0
  header = (uint8_t *)memdup(packet_payload, header_length);
813
0
  if(!header)
814
0
    return;
815
0
  header[0] = first_byte;
816
0
  for( i = 0; i < pkn_len; i++) {
817
0
    header[header_length - 1 - i] = (uint8_t)(packet_number >> (8 * i));
818
0
  }
819
820
  /* Input is "header || ciphertext (buffer) || auth tag (16 bytes)" */
821
0
  buffer_length = packet_payload_len - (header_length + 16);
822
0
  if(buffer_length == 0) {
823
0
    NDPI_LOG_DBG(ndpi_struct, "Decryption not possible, ciphertext is too short\n");
824
0
    ndpi_free(header);
825
0
    return;
826
0
  }
827
0
  buffer = (uint8_t *)memdup(packet_payload + header_length, buffer_length);
828
0
  if(!buffer) {
829
0
    ndpi_free(header);
830
0
    return;
831
0
  }
832
0
  memcpy(atag, packet_payload + header_length + buffer_length, 16);
833
834
0
  memcpy(nonce, pp_cipher->pp_iv, TLS13_AEAD_NONCE_LENGTH);
835
  /* Packet number is left-padded with zeroes and XORed with write_iv */
836
0
  phton64(nonce + sizeof(nonce) - 8, pntoh64(nonce + sizeof(nonce) - 8) ^ packet_number);
837
838
0
  gcry_cipher_reset(pp_cipher->pp_cipher);
839
0
  err = gcry_cipher_setiv(pp_cipher->pp_cipher, nonce, TLS13_AEAD_NONCE_LENGTH);
840
0
  if(err) {
841
0
    NDPI_LOG_DBG(ndpi_struct, "Decryption (setiv) failed: %s\n", __gcry_err(err, buferr, sizeof(buferr)));
842
0
    ndpi_free(header);
843
0
    ndpi_free(buffer);
844
0
    return;
845
0
  }
846
847
  /* associated data (A) is the contents of QUIC header */
848
0
  err = gcry_cipher_authenticate(pp_cipher->pp_cipher, header, header_length);
849
0
  if(err) {
850
0
    NDPI_LOG_DBG(ndpi_struct, "Decryption (authenticate) failed: %s\n", __gcry_err(err, buferr, sizeof(buferr)));
851
0
    ndpi_free(header);
852
0
    ndpi_free(buffer);
853
0
    return;
854
0
  }
855
856
0
  ndpi_free(header);
857
858
  /* Output ciphertext (C) */
859
0
  err = gcry_cipher_decrypt(pp_cipher->pp_cipher, buffer, buffer_length, NULL, 0);
860
0
  if(err) {
861
0
    NDPI_LOG_DBG(ndpi_struct, "Decryption (decrypt) failed: %s\n", __gcry_err(err, buferr, sizeof(buferr)));
862
0
    ndpi_free(buffer);
863
0
    return;
864
0
  }
865
866
0
  err = gcry_cipher_checktag(pp_cipher->pp_cipher, atag, 16);
867
0
  if(err) {
868
0
    NDPI_LOG_DBG(ndpi_struct, "Decryption (checktag) failed: %s\n", __gcry_err(err, buferr, sizeof(buferr)));
869
0
    ndpi_free(buffer);
870
0
    return;
871
0
  }
872
873
0
  result->data = buffer;
874
0
  result->data_len = buffer_length;
875
0
}
876
/**
877
 * Compute the client and server initial secrets given Connection ID "cid".
878
 */
879
static int quic_derive_initial_secrets(struct ndpi_detection_module_struct *ndpi_struct,
880
               uint32_t version,
881
               const uint8_t *cid, uint8_t cid_len,
882
               uint8_t client_initial_secret[HASH_SHA2_256_LENGTH])
883
0
{
884
  /*
885
   * https://tools.ietf.org/html/draft-ietf-quic-tls-29#section-5.2
886
   *
887
   * initial_secret = HKDF-Extract(initial_salt, client_dst_connection_id)
888
   *
889
   * client_initial_secret = HKDF-Expand-Label(initial_secret,
890
   *                                           "client in", "", Hash.length)
891
   *
892
   * Hash for handshake packets is SHA-256 (output size 32).
893
   */
894
0
  static const uint8_t handshake_salt_draft_22[20] = {
895
0
    0x7f, 0xbc, 0xdb, 0x0e, 0x7c, 0x66, 0xbb, 0xe9, 0x19, 0x3a,
896
0
    0x96, 0xcd, 0x21, 0x51, 0x9e, 0xbd, 0x7a, 0x02, 0x64, 0x4a
897
0
  };
898
0
  static const uint8_t handshake_salt_draft_23[20] = {
899
0
    0xc3, 0xee, 0xf7, 0x12, 0xc7, 0x2e, 0xbb, 0x5a, 0x11, 0xa7,
900
0
    0xd2, 0x43, 0x2b, 0xb4, 0x63, 0x65, 0xbe, 0xf9, 0xf5, 0x02,
901
0
  };
902
0
  static const uint8_t handshake_salt_draft_29[20] = {
903
0
    0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2, 0x4c, 0x9e, 0x97,
904
0
    0x86, 0xf1, 0x9c, 0x61, 0x11, 0xe0, 0x43, 0x90, 0xa8, 0x99
905
0
  };
906
0
  static const uint8_t hanshake_salt_draft_q50[20] = {
907
0
    0x50, 0x45, 0x74, 0xEF, 0xD0, 0x66, 0xFE, 0x2F, 0x9D, 0x94,
908
0
    0x5C, 0xFC, 0xDB, 0xD3, 0xA7, 0xF0, 0xD3, 0xB5, 0x6B, 0x45
909
0
  };
910
0
  static const uint8_t hanshake_salt_draft_t50[20] = {
911
0
    0x7f, 0xf5, 0x79, 0xe5, 0xac, 0xd0, 0x72, 0x91, 0x55, 0x80,
912
0
    0x30, 0x4c, 0x43, 0xa2, 0x36, 0x7c, 0x60, 0x48, 0x83, 0x10
913
0
  };
914
0
  static const uint8_t hanshake_salt_draft_t51[20] = {
915
0
    0x7a, 0x4e, 0xde, 0xf4, 0xe7, 0xcc, 0xee, 0x5f, 0xa4, 0x50,
916
0
    0x6c, 0x19, 0x12, 0x4f, 0xc8, 0xcc, 0xda, 0x6e, 0x03, 0x3d
917
0
  };
918
0
  static const uint8_t handshake_salt_v1[20] = {
919
0
    0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17,
920
0
    0x9a, 0xe6, 0xa4, 0xc8, 0x0c, 0xad, 0xcc, 0xbb, 0x7f, 0x0a
921
0
  };
922
0
  static const uint8_t handshake_salt_v2_draft_00[20] = {
923
0
    0x0d, 0xed, 0xe3, 0xde, 0xf7, 0x00, 0xa6, 0xdb, 0x81, 0x93,
924
0
    0x81, 0xbe, 0x6e, 0x26, 0x9d, 0xcb, 0xf9, 0xbd, 0x2e, 0xd9
925
0
  };
926
0
  gcry_error_t err;
927
0
  uint8_t secret[HASH_SHA2_256_LENGTH];
928
#ifdef NDPI_ENABLE_DEBUG_MESSAGES
929
  char buferr[128];
930
#endif
931
932
0
  if(version == V_Q050) {
933
0
    err = hkdf_extract(GCRY_MD_SHA256, hanshake_salt_draft_q50,
934
0
           sizeof(hanshake_salt_draft_q50),
935
0
                       cid, cid_len, secret);
936
0
  } else if(version == V_T050) {
937
0
    err = hkdf_extract(GCRY_MD_SHA256, hanshake_salt_draft_t50,
938
0
           sizeof(hanshake_salt_draft_t50),
939
0
                       cid, cid_len, secret);
940
0
  } else if(version == V_T051) {
941
0
    err = hkdf_extract(GCRY_MD_SHA256, hanshake_salt_draft_t51,
942
0
           sizeof(hanshake_salt_draft_t51),
943
0
                       cid, cid_len, secret);
944
0
  } else if(is_quic_ver_less_than(version, 22)) {
945
0
    err = hkdf_extract(GCRY_MD_SHA256, handshake_salt_draft_22,
946
0
           sizeof(handshake_salt_draft_22),
947
0
                       cid, cid_len, secret);
948
0
  } else if(is_quic_ver_less_than(version, 28)) {
949
0
    err = hkdf_extract(GCRY_MD_SHA256, handshake_salt_draft_23,
950
0
           sizeof(handshake_salt_draft_23),
951
0
                       cid, cid_len, secret);
952
0
  } else if(is_quic_ver_less_than(version, 32)) {
953
0
    err = hkdf_extract(GCRY_MD_SHA256, handshake_salt_draft_29,
954
0
           sizeof(handshake_salt_draft_29),
955
0
                       cid, cid_len, secret);
956
0
  } else if (is_quic_ver_less_than(version, 34)) {
957
0
    err = hkdf_extract(GCRY_MD_SHA256, handshake_salt_v1,
958
0
           sizeof(handshake_salt_v1),
959
0
                       cid, cid_len, secret);
960
0
  } else {
961
0
    err = hkdf_extract(GCRY_MD_SHA256, handshake_salt_v2_draft_00,
962
0
           sizeof(handshake_salt_v2_draft_00),
963
0
                       cid, cid_len, secret);
964
0
  }
965
0
  if(err) {
966
0
    NDPI_LOG_DBG(ndpi_struct, "Failed to extract secrets: %s\n", __gcry_err(err, buferr, sizeof(buferr)));
967
0
    return -1;
968
0
  }
969
970
0
  if(!quic_hkdf_expand_label(ndpi_struct, GCRY_MD_SHA256, secret, sizeof(secret), "client in",
971
0
           client_initial_secret, HASH_SHA2_256_LENGTH)) {
972
0
    NDPI_LOG_DBG(ndpi_struct, "Key expansion (client) failed: %s\n", __gcry_err(err, buferr, sizeof(buferr)));
973
0
    return -1;
974
0
  }
975
976
0
  return 0;
977
0
}
978
979
/*
980
 * End Wireshark code
981
 */
982
983
984
static uint8_t *decrypt_initial_packet(struct ndpi_detection_module_struct *ndpi_struct,
985
               const uint8_t *orig_dest_conn_id, uint8_t orig_dest_conn_id_len,
986
               uint8_t dest_conn_id_len,
987
               uint8_t source_conn_id_len, uint32_t version,
988
               uint32_t *clear_payload_len)
989
0
{
990
0
  uint64_t token_length, payload_length, packet_number;
991
0
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
992
0
  uint8_t first_byte;
993
0
  uint32_t pkn32, pn_offset, pkn_len, offset;
994
0
  quic_ciphers ciphers; /* Client initial ciphers */
995
0
  quic_decrypt_result_t decryption = { 0, 0};
996
0
  uint8_t client_secret[HASH_SHA2_256_LENGTH];
997
998
0
  memset(&ciphers, '\0', sizeof(ciphers));
999
0
  if(quic_derive_initial_secrets(ndpi_struct, version, orig_dest_conn_id, orig_dest_conn_id_len,
1000
0
         client_secret) != 0) {
1001
0
    NDPI_LOG_DBG(ndpi_struct, "Error quic_derive_initial_secrets\n");
1002
0
    return NULL;
1003
0
  }
1004
1005
  /* Packet numbers are protected with AES128-CTR,
1006
     Initial packets are protected with AEAD_AES_128_GCM. */
1007
0
  if(!quic_ciphers_prepare(ndpi_struct, &ciphers, GCRY_MD_SHA256,
1008
0
                           GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_GCM,
1009
0
                           client_secret, version)) {
1010
0
    NDPI_LOG_DBG(ndpi_struct, "Error quic_cipher_prepare\n");
1011
0
    return NULL;
1012
0
  }
1013
1014
  /* Type(1) + version(4) + DCIL + DCID + SCIL + SCID */
1015
0
  pn_offset = 1 + 4 + 1 + dest_conn_id_len + 1 + source_conn_id_len;
1016
0
  pn_offset += quic_len(&packet->payload[pn_offset], &token_length);
1017
0
  pn_offset += token_length;
1018
  /* Checks: quic_len reads 8 bytes, at most; quic_decrypt_header reads other 20 bytes.
1019
     Promote to uint64_t to avoid unsigned wrapping */
1020
0
  if((uint64_t)pn_offset + 8 + (4 + 16) >= (uint64_t)packet->payload_packet_len) {
1021
0
    quic_ciphers_reset(&ciphers);
1022
0
    return NULL;
1023
0
  }
1024
0
  pn_offset += quic_len(&packet->payload[pn_offset], &payload_length);
1025
1026
0
  NDPI_LOG_DBG2(ndpi_struct, "pn_offset %d token_length %d payload_length %d\n",
1027
0
    pn_offset, token_length, payload_length);
1028
1029
0
  if (pn_offset + payload_length > packet->payload_packet_len) {
1030
0
    NDPI_LOG_DBG(ndpi_struct, "Too short %d %d\n", pn_offset + payload_length,
1031
0
                 packet->payload_packet_len);
1032
0
    quic_ciphers_reset(&ciphers);
1033
0
    return NULL;
1034
0
  }
1035
1036
0
  if(!quic_decrypt_header(&packet->payload[0], pn_offset, &ciphers.hp_cipher,
1037
0
        GCRY_CIPHER_AES128, &first_byte, &pkn32, 0)) {
1038
0
    quic_ciphers_reset(&ciphers);
1039
0
    return NULL;
1040
0
  }
1041
0
  NDPI_LOG_DBG2(ndpi_struct, "first_byte 0x%x pkn32 0x%x\n", first_byte, pkn32);
1042
1043
0
  pkn_len = (first_byte & 3) + 1;
1044
  /* TODO: is it always true in Initial Packets? */
1045
0
  packet_number = pkn32;
1046
1047
0
  offset = pn_offset + pkn_len;
1048
0
  if (!(pn_offset + payload_length >= offset + 16)) {
1049
0
    NDPI_LOG_DBG(ndpi_struct, "No room for Auth Tag %d %d",
1050
0
                 pn_offset + payload_length, offset);
1051
0
    quic_ciphers_reset(&ciphers);
1052
0
    return NULL;
1053
0
  }
1054
0
  quic_decrypt_message(ndpi_struct, &ciphers.pp_cipher, &packet->payload[0], pn_offset + payload_length,
1055
0
           offset, first_byte, pkn_len, packet_number, &decryption);
1056
1057
0
  quic_ciphers_reset(&ciphers);
1058
1059
0
  if(decryption.data_len) {
1060
0
    *clear_payload_len = decryption.data_len;
1061
0
    return decryption.data;
1062
0
  }
1063
0
  return NULL;
1064
0
}
1065
1066
static void update_reasm_buf_bitmap(u_int8_t *buffer_bitmap,
1067
            const u_int32_t buffer_bitmap_size,
1068
            const u_int32_t recv_pos,
1069
            const u_int32_t recv_len)
1070
0
{
1071
0
  if (!recv_len || !buffer_bitmap_size || !buffer_bitmap || recv_pos + recv_len > buffer_bitmap_size * 8)
1072
0
    return;
1073
0
  const u_int32_t start_byte = recv_pos / 8;
1074
0
  const u_int32_t end_byte = (recv_pos + recv_len - 1) / 8;
1075
0
  const u_int32_t start_bit = recv_pos % 8;
1076
0
  const u_int32_t end_bit = (start_bit + recv_len - 1) % 8;
1077
0
  if (start_byte == end_byte)
1078
0
    buffer_bitmap[start_byte] |= (((1U << recv_len) - 1U) << start_bit); // fill from bit 'start_bit' until bit 'end_bit', both inclusive
1079
0
  else{
1080
0
    u_int32_t i;
1081
1082
0
    for (i = start_byte + 1; i <= end_byte - 1; i++)
1083
0
      buffer_bitmap[i] = 0xff; // completely received byte
1084
0
    buffer_bitmap[start_byte] |= ~((1U << start_bit) - 1U); // fill from bit 'start_bit' until bit 7, both inclusive
1085
0
    buffer_bitmap[end_byte] |= (1U << (end_bit + 1U)) - 1U; // fill from bit 0 until bit 'end_bit', both inclusive
1086
0
  }
1087
0
}
1088
1089
static int is_reasm_buf_complete(const u_int8_t *buffer_bitmap,
1090
                                 const u_int32_t buffer_len)
1091
0
{
1092
0
  const u_int32_t complete_bytes = buffer_len / 8;
1093
0
  const u_int32_t remaining_bits = buffer_len % 8;
1094
0
  u_int32_t i;
1095
1096
0
  if (!buffer_bitmap)
1097
0
    return 0;
1098
1099
0
  for(i = 0; i < complete_bytes; i++)
1100
0
    if (buffer_bitmap[i] != 0xff)
1101
0
      return 0;
1102
1103
0
  if (remaining_bits && buffer_bitmap[complete_bytes] != (1U << (remaining_bits)) - 1) 
1104
0
    return 0;
1105
    
1106
0
  return 1;
1107
0
}
1108
1109
static int __reassemble(struct ndpi_flow_struct *flow, const u_int8_t *frag,
1110
                        uint64_t frag_len, uint64_t frag_offset,
1111
                        const u_int8_t **buf, u_int64_t *buf_len)
1112
0
{
1113
0
  const uint64_t max_quic_reasm_buffer_len = 4096; /* Let's say a couple of full-MTU packets... Must be multiple of 8*/
1114
0
  const uint64_t quic_reasm_buffer_bitmap_len = max_quic_reasm_buffer_len / 8;
1115
0
  const uint64_t last_pos = frag_offset + frag_len;
1116
1117
0
  if(!flow->l4.udp.quic_reasm_buf) {
1118
0
    flow->l4.udp.quic_reasm_buf = (uint8_t *)ndpi_malloc(max_quic_reasm_buffer_len);
1119
0
    if(!flow->l4.udp.quic_reasm_buf_bitmap)
1120
0
      flow->l4.udp.quic_reasm_buf_bitmap = (uint8_t *)ndpi_calloc(quic_reasm_buffer_bitmap_len, sizeof(uint8_t));
1121
0
    if(!flow->l4.udp.quic_reasm_buf || !flow->l4.udp.quic_reasm_buf_bitmap)
1122
0
      return -1; /* Memory error */
1123
0
    flow->l4.udp.quic_reasm_buf_last_pos = 0;
1124
0
  }
1125
0
  if(last_pos > max_quic_reasm_buffer_len)
1126
0
    return -3; /* Buffer too small */
1127
1128
0
  memcpy(&flow->l4.udp.quic_reasm_buf[frag_offset], frag, frag_len);
1129
0
  flow->l4.udp.quic_reasm_buf_last_pos = last_pos > flow->l4.udp.quic_reasm_buf_last_pos ? last_pos : flow->l4.udp.quic_reasm_buf_last_pos;
1130
0
  update_reasm_buf_bitmap(flow->l4.udp.quic_reasm_buf_bitmap, quic_reasm_buffer_bitmap_len, frag_offset, frag_len); 
1131
1132
0
  *buf = flow->l4.udp.quic_reasm_buf;
1133
0
  *buf_len = flow->l4.udp.quic_reasm_buf_last_pos;
1134
0
  return 0;
1135
0
}
1136
static int is_ch_complete(const u_int8_t *buf, uint64_t buf_len)
1137
0
{
1138
0
  uint32_t msg_len;
1139
1140
0
  if(buf_len >= 4) {
1141
0
    msg_len = (buf[1] << 16) + (buf[2] << 8) + buf[3];
1142
0
    if (4 + msg_len == buf_len) {
1143
0
      return 1;
1144
0
    }
1145
0
  }
1146
0
  return 0;
1147
0
}
1148
static int is_ch_reassembler_pending(struct ndpi_flow_struct *flow)
1149
0
{
1150
0
  return flow->l4.udp.quic_reasm_buf != NULL &&
1151
0
    !(is_reasm_buf_complete(flow->l4.udp.quic_reasm_buf_bitmap, flow->l4.udp.quic_reasm_buf_last_pos)
1152
0
      && is_ch_complete(flow->l4.udp.quic_reasm_buf, flow->l4.udp.quic_reasm_buf_last_pos));
1153
0
}
1154
static const uint8_t *get_reassembled_crypto_data(struct ndpi_detection_module_struct *ndpi_struct,
1155
              struct ndpi_flow_struct *flow,
1156
              const u_int8_t *frag,
1157
              uint64_t frag_offset, uint64_t frag_len,
1158
              uint64_t *crypto_data_len)
1159
0
{
1160
0
  const u_int8_t *crypto_data;
1161
0
  int rc;
1162
1163
0
  NDPI_LOG_DBG2(ndpi_struct, "frag %d/%d\n", frag_offset, frag_len);
1164
1165
  /* Fast path: no need of reassembler stuff */
1166
0
  if(frag_offset == 0 &&
1167
0
     is_ch_complete(frag, frag_len)) {
1168
0
    NDPI_LOG_DBG2(ndpi_struct, "Complete CH (fast path)\n");
1169
0
    *crypto_data_len = frag_len;
1170
0
    return frag;
1171
0
  }
1172
1173
0
  rc = __reassemble(flow, frag, frag_len, frag_offset,
1174
0
                    &crypto_data, crypto_data_len);
1175
0
  if(rc == 0) {
1176
0
    if(is_reasm_buf_complete(flow->l4.udp.quic_reasm_buf_bitmap, *crypto_data_len) &&
1177
0
       is_ch_complete(crypto_data, *crypto_data_len)) {
1178
0
      NDPI_LOG_DBG2(ndpi_struct, "Reassembler completed!\n");
1179
0
      return crypto_data;
1180
0
    }
1181
0
    NDPI_LOG_DBG2(ndpi_struct, "CH not yet completed\n");
1182
0
  } else {
1183
0
    NDPI_LOG_DBG(ndpi_struct, "Reassembler error: %d\n", rc);
1184
0
  }
1185
0
  return NULL;
1186
0
}
1187
1188
const uint8_t *get_crypto_data(struct ndpi_detection_module_struct *ndpi_struct,
1189
             struct ndpi_flow_struct *flow,
1190
             u_int8_t *clear_payload, uint32_t clear_payload_len,
1191
             uint64_t *crypto_data_len)
1192
0
{
1193
0
  const u_int8_t *crypto_data = NULL;
1194
0
  uint32_t counter;
1195
0
  uint8_t first_nonzero_payload_byte, offset_len;
1196
0
  uint64_t unused, frag_offset, frag_len;
1197
0
  u_int32_t version = flow->protos.tls_quic.quic_version;
1198
1199
0
  counter = 0;
1200
0
  while(counter < clear_payload_len && clear_payload[counter] == 0)
1201
0
    counter += 1;
1202
0
  if(counter >= clear_payload_len)
1203
0
    return NULL;
1204
0
  first_nonzero_payload_byte = clear_payload[counter];
1205
0
  NDPI_LOG_DBG2(ndpi_struct, "first_nonzero_payload_byte 0x%x\n", first_nonzero_payload_byte);
1206
0
  if(is_gquic_ver_less_than(version, 46)) {
1207
0
    if(first_nonzero_payload_byte == 0x40 ||
1208
0
       first_nonzero_payload_byte == 0x60) {
1209
      /* Probably an ACK/NACK frame: this CHLO is not the first one but try
1210
         decoding it nonetheless */
1211
0
      counter += (first_nonzero_payload_byte == 0x40) ? 6 : 9;
1212
0
      if(counter >= clear_payload_len)
1213
0
        return NULL;
1214
0
      first_nonzero_payload_byte = clear_payload[counter];
1215
0
    }
1216
0
    if((first_nonzero_payload_byte != 0xA0) &&
1217
0
       (first_nonzero_payload_byte != 0xA4)) {
1218
0
      NDPI_LOG_DBG(ndpi_struct, "Unexpected frame 0x%x version 0x%x\n",\
1219
0
       first_nonzero_payload_byte, version);
1220
0
      return NULL;
1221
0
    }
1222
0
    offset_len = (first_nonzero_payload_byte & 0x1C) >> 2;
1223
0
    if(offset_len > 0)
1224
0
      offset_len += 1;
1225
0
    if(counter + 2 + offset_len + 2 /*gquic_get_u16 reads 2 bytes */  > clear_payload_len)
1226
0
      return NULL;
1227
0
    if(clear_payload[counter + 1] != 0x01) {
1228
0
      NDPI_LOG_DBG(ndpi_struct, "Unexpected stream ID version 0x%x\n", version);
1229
0
      return NULL;
1230
0
    }
1231
0
    counter += 2 + offset_len;
1232
0
    *crypto_data_len = gquic_get_u16(&clear_payload[counter], version);
1233
0
    counter += 2;
1234
0
    if(*crypto_data_len + counter > clear_payload_len) {
1235
0
      NDPI_LOG_DBG(ndpi_struct, "Invalid length %lu + %d > %d version 0x%x\n",
1236
0
       (unsigned long)*crypto_data_len, counter, clear_payload_len, version);
1237
0
      return NULL;
1238
0
    }
1239
0
    crypto_data = &clear_payload[counter];
1240
1241
0
  } else if(version == V_Q050 || version == V_T050 || version == V_T051) {
1242
0
    if(first_nonzero_payload_byte == 0x40 ||
1243
0
       first_nonzero_payload_byte == 0x60) {
1244
      /* Probably an ACK/NACK frame: this CHLO is not the first one but try
1245
         decoding it nonetheless */
1246
0
      counter += (first_nonzero_payload_byte == 0x40) ? 6 : 9;
1247
0
      if(counter >= clear_payload_len)
1248
0
        return NULL;
1249
0
      first_nonzero_payload_byte = clear_payload[counter];
1250
0
    }
1251
0
    if(first_nonzero_payload_byte != 0x08) {
1252
0
      NDPI_LOG_DBG(ndpi_struct, "Unexpected frame 0x%x\n", first_nonzero_payload_byte);
1253
0
      return NULL;
1254
0
    }
1255
0
    counter += 1;
1256
0
    if(counter + 8 + 8 >= clear_payload_len) /* quic_len reads 8 bytes, at most */
1257
0
      return NULL;
1258
0
    counter += quic_len(&clear_payload[counter], &unused);
1259
0
    counter += quic_len(&clear_payload[counter], crypto_data_len);
1260
0
    if(*crypto_data_len + counter > clear_payload_len) {
1261
0
      NDPI_LOG_DBG(ndpi_struct, "Invalid length %lu + %d > %d version 0x%x\n",
1262
0
       (unsigned long)*crypto_data_len, counter, clear_payload_len, version);
1263
0
      return NULL;
1264
0
    }
1265
0
    crypto_data = &clear_payload[counter];
1266
1267
0
  } else {  /* All other versions */
1268
0
    while(counter < clear_payload_len) {
1269
0
      uint8_t frame_type = clear_payload[counter];
1270
0
      switch(frame_type) {
1271
0
      case 0x00:
1272
0
        NDPI_LOG_DBG2(ndpi_struct, "PADDING frame\n");
1273
0
        while(counter < clear_payload_len &&
1274
0
              clear_payload[counter] == 0)
1275
0
          counter += 1;
1276
0
        break;
1277
0
      case 0x01:
1278
0
        NDPI_LOG_DBG2(ndpi_struct, "PING frame\n");
1279
0
        counter += 1;
1280
0
        break;
1281
0
      case 0x06:
1282
0
        NDPI_LOG_DBG2(ndpi_struct, "CRYPTO frame\n");
1283
0
        counter += 1;
1284
0
        if(counter >= clear_payload_len ||
1285
0
           counter + quic_len_buffer_still_required(clear_payload[counter]) >= clear_payload_len)
1286
0
          return NULL;
1287
0
        counter += quic_len(&clear_payload[counter], &frag_offset);
1288
0
        if(counter >= clear_payload_len ||
1289
0
           counter + quic_len_buffer_still_required(clear_payload[counter]) >= clear_payload_len)
1290
0
          return NULL;
1291
0
        counter += quic_len(&clear_payload[counter], &frag_len);
1292
0
        if(frag_len + counter > clear_payload_len) {
1293
0
          NDPI_LOG_DBG(ndpi_struct, "Invalid crypto frag length %lu + %d > %d version 0x%x\n",
1294
0
                       (unsigned long)frag_len, counter, clear_payload_len, version);
1295
0
          return NULL;
1296
0
        }
1297
0
        crypto_data = get_reassembled_crypto_data(ndpi_struct, flow,
1298
0
                                                  &clear_payload[counter],
1299
0
                                                  frag_offset, frag_len,
1300
0
                                                  crypto_data_len);
1301
0
        if(crypto_data) {
1302
0
          return crypto_data;
1303
0
  }
1304
0
        NDPI_LOG_DBG(ndpi_struct, "Crypto reassembler pending\n");
1305
0
        counter += frag_len;
1306
0
        break;
1307
0
      case 0x1C: /* CC */
1308
0
      case 0x02: /* ACK */
1309
0
        NDPI_LOG_DBG2(ndpi_struct, "Unexpected CC/ACK frame\n");
1310
0
        return NULL;
1311
0
      default:
1312
0
        NDPI_LOG_DBG(ndpi_struct, "Unexpected frame 0x%x\n", frame_type);
1313
0
  return NULL;
1314
0
      }
1315
0
    }
1316
0
    if(counter > clear_payload_len) {
1317
0
      NDPI_LOG_DBG(ndpi_struct, "Error parsing frames %d %d\n", counter, clear_payload_len);
1318
0
      return NULL;
1319
0
    }
1320
0
  }
1321
0
  return crypto_data;
1322
0
}
1323
1324
static uint8_t *get_clear_payload(struct ndpi_detection_module_struct *ndpi_struct,
1325
          struct ndpi_flow_struct *flow,
1326
          uint32_t version, uint32_t *clear_payload_len)
1327
0
{
1328
0
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
1329
0
  u_int8_t *clear_payload;
1330
0
  u_int8_t dest_conn_id_len;
1331
0
  u_int8_t source_conn_id_len;
1332
1333
0
  if(is_gquic_ver_less_than(version, 43)) {
1334
0
    clear_payload = (uint8_t *)&packet->payload[26];
1335
0
    *clear_payload_len = packet->payload_packet_len - 26;
1336
    /* Skip Private-flag field for version for < Q34 */
1337
0
    if(is_gquic_ver_less_than(version, 33)) {
1338
0
      clear_payload += 1;
1339
0
      (*clear_payload_len) -= 1;
1340
0
    }
1341
0
  } else if(version == V_Q046) {
1342
0
    if(packet->payload[5] != 0x50) {
1343
0
      NDPI_LOG_DBG(ndpi_struct, "Q46 invalid conn id len 0x%x\n",
1344
0
       packet->payload[5]);
1345
0
      return NULL;
1346
0
    }
1347
0
    clear_payload = (uint8_t *)&packet->payload[30];
1348
0
    *clear_payload_len = packet->payload_packet_len - 30;
1349
0
  } else {
1350
    /* Upper limit of CIDs length has been already validated. If dest_conn_id_len is 0,
1351
       this is probably the Initial Packet from the server */
1352
0
    dest_conn_id_len = packet->payload[5];
1353
0
    if(dest_conn_id_len == 0) {
1354
0
      NDPI_LOG_DBG(ndpi_struct, "Packet 0x%x with dest_conn_id_len %d\n",
1355
0
       version, dest_conn_id_len);
1356
0
      return NULL;
1357
0
    }
1358
1359
0
    source_conn_id_len = packet->payload[6 + dest_conn_id_len];
1360
0
    const u_int8_t *dest_conn_id = &packet->payload[6];
1361
1362
    /* For initializing the ciphers we need the DCID of the very first Initial
1363
       sent by the client. This is quite important when CH is fragmented into multiple
1364
       packets and these packets have different DCID */
1365
0
    if(flow->l4.udp.quic_orig_dest_conn_id_len == 0) {
1366
0
      memcpy(flow->l4.udp.quic_orig_dest_conn_id,
1367
0
             dest_conn_id, dest_conn_id_len);
1368
0
      flow->l4.udp.quic_orig_dest_conn_id_len = dest_conn_id_len;
1369
0
    }
1370
1371
0
    clear_payload = decrypt_initial_packet(ndpi_struct,
1372
0
             flow->l4.udp.quic_orig_dest_conn_id,
1373
0
             flow->l4.udp.quic_orig_dest_conn_id_len,
1374
0
             dest_conn_id_len,
1375
0
             source_conn_id_len, version,
1376
0
             clear_payload_len);
1377
0
  }
1378
1379
0
  return clear_payload;
1380
0
}
1381
1382
void process_tls(struct ndpi_detection_module_struct *ndpi_struct,
1383
     struct ndpi_flow_struct *flow,
1384
     const u_int8_t *crypto_data, uint32_t crypto_data_len)
1385
0
{
1386
0
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
1387
1388
  /* Overwriting packet payload */
1389
0
  u_int16_t p_len;
1390
0
  const u_int8_t *p;
1391
0
  p = packet->payload;
1392
0
  p_len = packet->payload_packet_len;
1393
0
  packet->payload = crypto_data;
1394
0
  packet->payload_packet_len = crypto_data_len;
1395
1396
0
  processClientServerHello(ndpi_struct, flow, flow->protos.tls_quic.quic_version);
1397
0
  flow->protos.tls_quic.client_hello_processed = 1; /* Allow matching of custom categories */
1398
1399
  /* Restore */
1400
0
  packet->payload = p;
1401
0
  packet->payload_packet_len = p_len;
1402
1403
  /* ServerHello is not needed to sub-classified QUIC, so we ignore it:
1404
     this way we lose JA3S and negotiated ciphers...
1405
     Negotiated version is only present in the ServerHello message too, but
1406
     fortunately, QUIC always uses TLS version 1.3 */
1407
0
  flow->protos.tls_quic.ssl_version = 0x0304;
1408
1409
  /* DNS-over-QUIC: ALPN is "doq" or "doq-XXX" (for drafts versions) */
1410
0
  if(flow->protos.tls_quic.advertised_alpns &&
1411
0
     strncmp(flow->protos.tls_quic.advertised_alpns, "doq", 3) == 0) {
1412
0
    NDPI_LOG_DBG(ndpi_struct, "Found DOQ (ALPN: [%s])\n", flow->protos.tls_quic.advertised_alpns);
1413
0
    ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_DOH_DOT, NDPI_PROTOCOL_QUIC, NDPI_CONFIDENCE_DPI);
1414
0
  }
1415
0
}
1416
void process_chlo(struct ndpi_detection_module_struct *ndpi_struct,
1417
      struct ndpi_flow_struct *flow,
1418
      const u_int8_t *crypto_data, uint32_t crypto_data_len)
1419
0
{
1420
0
  const uint8_t *tag;
1421
0
  uint32_t i;
1422
0
  uint16_t num_tags;
1423
0
  uint32_t prev_offset;
1424
0
  uint32_t tag_offset_start, offset, len;
1425
0
  ndpi_protocol_match_result ret_match;
1426
0
  int sni_found = 0, icsl_found = 0;
1427
1428
0
  if(crypto_data_len < 6)
1429
0
    return;
1430
0
  if(memcmp(crypto_data, "CHLO", 4) != 0) {
1431
0
    NDPI_LOG_DBG(ndpi_struct, "Unexpected handshake message");
1432
0
    return;
1433
0
  }
1434
0
  num_tags = le16toh(*(uint16_t *)&crypto_data[4]);
1435
1436
0
  tag_offset_start = 8 + 8 * num_tags;
1437
0
  prev_offset = 0;
1438
0
  for(i = 0; i < num_tags; i++) {
1439
0
    if(8 + 8 * i + 8 >= crypto_data_len)
1440
0
      break;
1441
0
    tag = &crypto_data[8 + 8 * i];
1442
0
    offset = le32toh(*((u_int32_t *)&crypto_data[8 + 8 * i + 4]));
1443
0
    if(prev_offset > offset)
1444
0
      break;
1445
0
    len = offset - prev_offset;
1446
    /* Promote to uint64_t to avoid unsigned wrapping */
1447
0
    if((uint64_t)tag_offset_start + prev_offset + len > (uint64_t)crypto_data_len)
1448
0
      break;
1449
#if 0
1450
    printf("crypto_data_len %u tag_offset_start %u prev_offset %u offset %u len %u\n",
1451
     crypto_data_len, tag_offset_start, prev_offset, offset, len);
1452
#endif
1453
0
    if(memcmp(tag, "SNI\0", 4) == 0) {
1454
1455
0
      ndpi_hostname_sni_set(flow, &crypto_data[tag_offset_start + prev_offset], len, NDPI_HOSTNAME_NORM_ALL);
1456
1457
0
      NDPI_LOG_DBG2(ndpi_struct, "SNI: [%s]\n",
1458
0
                    flow->host_server_name);
1459
1460
0
      ndpi_match_host_subprotocol(ndpi_struct, flow,
1461
0
                                  flow->host_server_name,
1462
0
                                  strlen(flow->host_server_name),
1463
0
                                  &ret_match, NDPI_PROTOCOL_QUIC, 1);
1464
0
      flow->protos.tls_quic.client_hello_processed = 1; /* Allow matching of custom categories */
1465
1466
0
      ndpi_check_dga_name(ndpi_struct, flow,
1467
0
                          flow->host_server_name, 1, 0, 0);
1468
1469
0
      if(ndpi_is_valid_hostname((char *)&crypto_data[tag_offset_start + prev_offset],
1470
0
        len) == 0) {
1471
0
        if(is_flowrisk_info_enabled(ndpi_struct, NDPI_INVALID_CHARACTERS)) {
1472
0
          char str[128];
1473
1474
0
    snprintf(str, sizeof(str), "Invalid host %s", flow->host_server_name);
1475
0
    ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, str);
1476
0
        } else {
1477
0
          ndpi_set_risk(ndpi_struct, flow, NDPI_INVALID_CHARACTERS, NULL);
1478
0
        }
1479
  
1480
  /* This looks like an attack */
1481
0
  ndpi_set_risk(ndpi_struct, flow, NDPI_POSSIBLE_EXPLOIT, "Suspicious hostname: attack ?");
1482
0
      }
1483
      
1484
0
      sni_found = 1;
1485
0
      if(icsl_found)
1486
0
        return;
1487
0
    }
1488
1489
0
    if(memcmp(tag, "ICSL", 4) == 0 && len >= 4) {
1490
0
      u_int icsl_offset = tag_offset_start + prev_offset;
1491
1492
0
      flow->protos.tls_quic.quic_idle_timeout_sec = le32toh((*(uint32_t *)&crypto_data[icsl_offset]));
1493
0
      NDPI_LOG_DBG2(ndpi_struct, "ICSL: %d\n", flow->protos.tls_quic.quic_idle_timeout_sec);
1494
0
      icsl_found = 1;
1495
1496
0
      if(sni_found)
1497
0
        return;
1498
0
    }
1499
1500
0
    prev_offset = offset;
1501
0
  }
1502
0
  if(i != num_tags)
1503
0
    NDPI_LOG_DBG(ndpi_struct, "Something went wrong in tags iteration\n");
1504
1505
  /* Add check for missing SNI */
1506
0
  if(flow->host_server_name[0] == '\0') {
1507
    /* This is a bit suspicious */
1508
0
    ndpi_set_risk(ndpi_struct, flow, NDPI_TLS_MISSING_SNI, "SNI should be present all time: attack ?");
1509
0
  }
1510
0
}
1511
1512
static int may_be_gquic_rej(struct ndpi_detection_module_struct *ndpi_struct)
1513
0
{
1514
0
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
1515
0
  void *ptr;
1516
1517
  /* Common case: msg from server default port */
1518
0
  if(packet->udp->source != ntohs(443))
1519
0
    return 0;
1520
  /* GQUIC. Common case: cid length 8, no version, packet number length 1 */
1521
0
  if(packet->payload[0] != 0x08)
1522
0
    return 0;
1523
0
  if(packet->payload_packet_len < 1 + 8 + 1 + 12 /* Message auth hash */ + 16 /* Arbitrary length */)
1524
0
    return 0;
1525
  /* Search for "REJ" tag in the first 16 bytes after the hash */
1526
0
  ptr = memchr(&packet->payload[1 + 8 + 1 + 12], 'R', 16 - 3);
1527
0
  if(ptr && memcmp(ptr, "REJ", 3) == 0)
1528
0
    return 1;
1529
0
  return 0;
1530
0
}
1531
1532
static int may_be_sh(struct ndpi_detection_module_struct *ndpi_struct,
1533
         struct ndpi_flow_struct *flow)
1534
0
{
1535
0
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
1536
0
  u_int8_t last_byte;
1537
1538
0
  if((packet->payload[0] & 0x40) == 0)
1539
0
    return 0;
1540
0
  if(packet->udp->dest != ntohs(443)) {
1541
0
    if(packet->udp->source ==  ntohs(443)) {
1542
0
      return -1; /* Keep looking for packets sent by the client */
1543
0
    }
1544
0
    return 0;
1545
0
  }
1546
1547
  /* SH packet sent by the client */
1548
1549
  /* QUIC never retransmits packet, but we should also somehow check that
1550
   * these 3 packets from the client are really different from each other
1551
   * to avoid matching retransmissions on some other protocols.
1552
   * To avoid saving too much state, simply check the last byte of each packet
1553
   * (the idea is that being QUIC fully encrypted, the bytes are somehow always
1554
   * different; a weak assumption, but it allow us to save only 1 byte in
1555
   * flow structure and it seems to work)
1556
   * TODO: do we need something better?
1557
   */
1558
1559
0
  if(packet->payload_packet_len < 1 + QUIC_SERVER_CID_HEURISTIC_LENGTH)
1560
0
    return 0;
1561
0
  last_byte = packet->payload[packet->payload_packet_len - 1];
1562
0
  if(flow->l4.udp.quic_server_cid_stage > 0) {
1563
0
    if(memcmp(flow->l4.udp.quic_server_cid, &packet->payload[1],
1564
0
              QUIC_SERVER_CID_HEURISTIC_LENGTH) != 0 ||
1565
0
       flow->l4.udp.quic_client_last_byte == last_byte)
1566
0
      return 0;
1567
0
    flow->l4.udp.quic_server_cid_stage++;
1568
0
    if(flow->l4.udp.quic_server_cid_stage == 3) {
1569
      /* Found QUIC via 3 SHs by client */
1570
0
      return 1;
1571
0
    }
1572
0
  } else {
1573
0
    memcpy(flow->l4.udp.quic_server_cid, &packet->payload[1], QUIC_SERVER_CID_HEURISTIC_LENGTH);
1574
0
    flow->l4.udp.quic_server_cid_stage = 1;
1575
0
  }
1576
0
  flow->l4.udp.quic_client_last_byte = last_byte;
1577
0
  return -1; /* Keep looking for other packets sent by client */
1578
0
}
1579
1580
static int may_be_0rtt(struct ndpi_detection_module_struct *ndpi_struct,
1581
           uint32_t *version)
1582
0
{
1583
0
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
1584
0
  u_int8_t first_byte;
1585
0
  u_int8_t pub_bit1, pub_bit2, pub_bit3, pub_bit4;
1586
0
  u_int8_t dest_conn_id_len, source_conn_id_len;
1587
1588
  /* First byte + version + dest_conn_id_len */
1589
0
  if(packet->payload_packet_len < 5 + 1) {
1590
0
    NDPI_LOG_DBG2(ndpi_struct, "Pkt too short\n");
1591
0
    return 0;
1592
0
  }
1593
1594
0
  first_byte = packet->payload[0];
1595
0
  pub_bit1 = ((first_byte & 0x80) != 0);
1596
0
  pub_bit2 = ((first_byte & 0x40) != 0);
1597
0
  pub_bit3 = ((first_byte & 0x20) != 0);
1598
0
  pub_bit4 = ((first_byte & 0x10) != 0);
1599
1600
0
  *version = ntohl(*((u_int32_t *)&packet->payload[1]));
1601
1602
  /* IETF versions, Long header, fixed bit (ignore QUIC-bit-greased case), 0RTT */
1603
1604
0
  if(!(is_version_quic(*version) &&
1605
0
       pub_bit1 && pub_bit2)) {
1606
0
    NDPI_LOG_DBG2(ndpi_struct, "Invalid header or version\n");
1607
0
    return 0;
1608
0
  }
1609
0
  if(!is_version_quic_v2(*version) &&
1610
0
     (pub_bit3 != 0 || pub_bit4 != 1)) {
1611
0
    NDPI_LOG_DBG2(ndpi_struct, "Version 0x%x not 0-RTT Packet\n", *version);
1612
0
    return 0;
1613
0
  }
1614
0
  if(is_version_quic_v2(*version) &&
1615
0
     (pub_bit3 != 1 || pub_bit4 != 0)) {
1616
0
    NDPI_LOG_DBG2(ndpi_struct, "Version 0x%x not 0-RTT Packet\n", *version);
1617
0
    return 0;
1618
0
  }
1619
1620
  /* Check that CIDs lengths are valid */
1621
0
  dest_conn_id_len = packet->payload[5];
1622
0
  if(packet->payload_packet_len <= 5 + 1 + dest_conn_id_len) {
1623
0
    NDPI_LOG_DBG2(ndpi_struct, "Dcid too short\n");
1624
0
    return 0;
1625
0
  }
1626
0
  source_conn_id_len = packet->payload[5 + 1 + dest_conn_id_len];
1627
0
  if(packet->payload_packet_len <= 5 + 1 + dest_conn_id_len + 1 + source_conn_id_len) {
1628
0
    NDPI_LOG_DBG2(ndpi_struct, "Scid too short\n");
1629
0
    return 0;
1630
0
  }
1631
0
  if(dest_conn_id_len > QUIC_MAX_CID_LENGTH ||
1632
0
     source_conn_id_len > QUIC_MAX_CID_LENGTH) {
1633
0
    NDPI_LOG_DBG2(ndpi_struct, "Version 0x%x invalid CIDs length %u %u\n",
1634
0
                  *version, dest_conn_id_len, source_conn_id_len);
1635
0
    return 0;
1636
0
  }
1637
1638
0
  return 1;
1639
0
}
1640
1641
static int may_be_initial_pkt(struct ndpi_detection_module_struct *ndpi_struct,
1642
            uint32_t *version)
1643
0
{
1644
0
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
1645
0
  u_int8_t first_byte;
1646
0
  u_int8_t pub_bit1, pub_bit2, pub_bit3, pub_bit4, pub_bit5, pub_bit7, pub_bit8;
1647
0
  u_int8_t dest_conn_id_len, source_conn_id_len;
1648
1649
  /* According to draft-ietf-quic-transport-29: "Clients MUST ensure that UDP
1650
     datagrams containing Initial packets have UDP payloads of at least 1200
1651
     bytes". Similar limit exists for previous versions */
1652
0
  if(packet->payload_packet_len < 1200) {
1653
0
    return 0;
1654
0
  }
1655
1656
0
  first_byte = packet->payload[0];
1657
0
  pub_bit1 = ((first_byte & 0x80) != 0);
1658
0
  pub_bit2 = ((first_byte & 0x40) != 0);
1659
0
  pub_bit3 = ((first_byte & 0x20) != 0);
1660
0
  pub_bit4 = ((first_byte & 0x10) != 0);
1661
0
  pub_bit5 = ((first_byte & 0x08) != 0);
1662
0
  pub_bit7 = ((first_byte & 0x02) != 0);
1663
0
  pub_bit8 = ((first_byte & 0x01) != 0);
1664
1665
0
  *version = 0;
1666
0
  if(pub_bit1) {
1667
0
    *version = ntohl(*((u_int32_t *)&packet->payload[1]));
1668
0
  } else if(pub_bit5 && !pub_bit2) {
1669
0
    if(!pub_bit8) {
1670
0
      NDPI_LOG_DBG2(ndpi_struct, "Packet without version\n")
1671
0
  } else {
1672
0
      *version = ntohl(*((u_int32_t *)&packet->payload[9]));
1673
0
    }
1674
0
  }
1675
0
  if(!is_version_valid(*version)) {
1676
0
    NDPI_LOG_DBG2(ndpi_struct, "Invalid version 0x%x\n", *version);
1677
0
    return 0;
1678
0
  }
1679
1680
0
  if(is_gquic_ver_less_than(*version, 43) &&
1681
0
     (!pub_bit5 || pub_bit3 != 0 || pub_bit4 != 0)) {
1682
0
    NDPI_LOG_DBG(ndpi_struct, "Version 0x%x invalid flags 0x%x\n", *version, first_byte);
1683
0
    return 0;
1684
0
  }
1685
0
  if((*version == V_Q046) &&
1686
0
     (pub_bit7 != 1 || pub_bit8 != 1)) {
1687
0
    NDPI_LOG_DBG(ndpi_struct, "Q46 invalid flag 0x%x\n", first_byte);
1688
0
    return 0;
1689
0
  }
1690
0
  if(((is_version_quic(*version) && !is_version_quic_v2(*version)) ||
1691
0
      (*version == V_Q046) || (*version == V_Q050)) &&
1692
0
     (pub_bit3 != 0 || pub_bit4 != 0)) {
1693
0
    NDPI_LOG_DBG2(ndpi_struct, "Version 0x%x not Initial Packet\n", *version);
1694
0
    return 0;
1695
0
  }
1696
0
  if(is_version_quic_v2(*version) &&
1697
0
     (pub_bit3 != 0 || pub_bit4 != 1)) {
1698
0
    NDPI_LOG_DBG2(ndpi_struct, "Version 0x%x not Initial Packet\n", *version);
1699
0
    return 0;
1700
0
  }
1701
1702
  /* Forcing Version Negotiation packets are QUIC Initial Packets (i.e.
1703
     Long Header). It should also be quite rare that a client sends this kind
1704
     of traffic with the QUIC bit greased i.e. having a server token.
1705
     Accordind to https://tools.ietf.org/html/draft-thomson-quic-bit-grease-00#section-3.1
1706
     "A client MAY also clear the QUIC Bit in Initial packets that are sent
1707
     to establish a new connection.  A client can only clear the QUIC Bit
1708
     if the packet includes a token provided by the server in a NEW_TOKEN
1709
     frame on a connection where the server also included the
1710
     grease_quic_bit transport parameter." */
1711
0
  if(is_version_forcing_vn(*version) &&
1712
0
     !(pub_bit1 == 1 && pub_bit2 == 1)) {
1713
0
    NDPI_LOG_DBG2(ndpi_struct, "Version 0x%x with first byte 0x%x\n", *version, first_byte);
1714
0
    return 0;
1715
0
  }
1716
1717
  /* Check that CIDs lengths are valid: QUIC limits the CID length to 20 */
1718
0
  if(is_version_with_ietf_long_header(*version)) {
1719
0
    dest_conn_id_len = packet->payload[5];
1720
0
    source_conn_id_len = packet->payload[5 + 1 + dest_conn_id_len];
1721
0
    if (dest_conn_id_len > QUIC_MAX_CID_LENGTH ||
1722
0
        source_conn_id_len > QUIC_MAX_CID_LENGTH) {
1723
0
      NDPI_LOG_DBG2(ndpi_struct, "Version 0x%x invalid CIDs length %u %u",
1724
0
        *version, dest_conn_id_len, source_conn_id_len);
1725
0
      return 0;
1726
0
    }
1727
0
  }
1728
1729
  /* TODO: add some other checks to avoid false positives */
1730
1731
0
  return 1;
1732
0
}
1733
1734
/* ***************************************************************** */
1735
1736
static int eval_extra_processing(struct ndpi_detection_module_struct *ndpi_struct,
1737
                                 struct ndpi_flow_struct *flow)
1738
0
{
1739
0
  u_int32_t version = flow->protos.tls_quic.quic_version;
1740
1741
  /* For the time being we need extra processing in two cases only:
1742
     1) to detect Snapchat calls, i.e. RTP/RTCP multiplxed with QUIC.
1743
        Two cases:
1744
        a) [old] Q046, without any SNI
1745
        b) v1 with SNI *.addlive.io
1746
     2) to reassemble CH fragments on multiple UDP packets.
1747
     These two cases are mutually exclusive
1748
  */
1749
1750
0
  if(version == V_Q046 && flow->host_server_name[0] == '\0') {
1751
0
    NDPI_LOG_DBG2(ndpi_struct, "We have further work to do (old snapchat call?)\n");
1752
0
    return 1;
1753
0
  }
1754
1755
0
  if(version == V_1 &&
1756
0
     flow->detected_protocol_stack[0] == NDPI_PROTOCOL_SNAPCHAT) {
1757
0
    size_t sni_len = strlen(flow->host_server_name);
1758
0
    if(sni_len > 11 &&
1759
0
       strcmp(flow->host_server_name + sni_len - 11, ".addlive.io") == 0) {
1760
0
      NDPI_LOG_DBG2(ndpi_struct, "We have further work to do (new snapchat call?)\n");
1761
0
      return 1;
1762
0
    }
1763
0
  }
1764
1765
0
  if(is_ch_reassembler_pending(flow)) {
1766
0
    NDPI_LOG_DBG2(ndpi_struct, "We have further work to do (reasm)\n");
1767
0
    return 1;
1768
0
  }
1769
1770
0
  return 0;
1771
0
}
1772
1773
static void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct,
1774
           struct ndpi_flow_struct *flow);
1775
static int ndpi_search_quic_extra(struct ndpi_detection_module_struct *ndpi_struct,
1776
          struct ndpi_flow_struct *flow)
1777
0
{
1778
0
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
1779
1780
  /* We are elaborating a packet following the initial CHLO/ClientHello.
1781
     Two cases:
1782
     1) Mutiplexing QUIC with RTP/RTCP. It should be quite generic, but
1783
     for the time being, we known only NDPI_PROTOCOL_SNAPCHAT_CALL having
1784
     such behaviour
1785
     2) CH reasssembling is going on */
1786
  /* TODO: could we unify ndpi_search_quic() and ndpi_search_quic_extra() somehow? */
1787
1788
0
  NDPI_LOG_DBG(ndpi_struct, "search QUIC extra func\n");
1789
1790
0
  if(packet->payload_packet_len == 0)
1791
0
    return 1;
1792
1793
0
  if (is_ch_reassembler_pending(flow)) {
1794
0
    ndpi_search_quic(ndpi_struct, flow);
1795
0
    if(is_ch_reassembler_pending(flow))
1796
0
      return 1;
1797
0
    flow->extra_packets_func = NULL;
1798
0
    return 0;
1799
0
  }
1800
1801
  /* RTP/RTCP stuff */
1802
1803
  /* If this packet is still a Q046 one we need to keep going */
1804
0
  if(packet->payload[0] & 0x40) {
1805
0
    NDPI_LOG_DBG(ndpi_struct, "Still QUIC\n");
1806
0
    return 1; /* Keep going */
1807
0
  }
1808
1809
0
  NDPI_LOG_DBG2(ndpi_struct, "No more QUIC: nothing to do on QUIC side\n");
1810
0
  flow->extra_packets_func = NULL;
1811
1812
  /* This might be a RTP/RTCP stream: let's check it */
1813
  /* TODO: the cleanest solution should be triggering the rtp/rtcp dissector, but
1814
     I have not been able to that that so I reimplemented a basic RTP/RTCP detection.*/
1815
0
  if((packet->payload[0] >> 6) == 2 && /* Version 2 */
1816
0
     packet->payload_packet_len > 1 &&
1817
0
     (packet->payload[1] == 201 || /* RTCP, Receiver Report */
1818
0
      packet->payload[1] == 200 || /* RTCP, Sender Report */
1819
0
      is_valid_rtp_payload_type(packet->payload[1] & 0x7F)) /* RTP */) {
1820
0
    ndpi_master_app_protocol proto;
1821
1822
0
    NDPI_LOG_DBG(ndpi_struct, "Found RTP/RTCP over QUIC\n");
1823
0
    ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SNAPCHAT_CALL, NDPI_PROTOCOL_QUIC, NDPI_CONFIDENCE_DPI);
1824
    /* In "extra_eval" data path, if we change the classification, we need to update the category, too */
1825
0
    proto.master_protocol = NDPI_PROTOCOL_QUIC;
1826
0
    proto.app_protocol = NDPI_PROTOCOL_SNAPCHAT_CALL;
1827
0
    flow->category = get_proto_category(ndpi_struct, proto);
1828
0
    flow->breed = get_proto_breed(ndpi_struct, proto);
1829
0
  } else {
1830
    /* Unexpected traffic pattern: we should investigate it... */
1831
0
    NDPI_LOG_INFO(ndpi_struct, "To investigate...\n");
1832
0
  }
1833
1834
0
  return 0;
1835
0
}
1836
1837
static int is_vn(struct ndpi_detection_module_struct *ndpi_struct)
1838
0
{
1839
0
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
1840
0
  u_int32_t version;
1841
0
  u_int8_t first_byte;
1842
0
  u_int8_t pub_bit1;
1843
0
  u_int8_t dest_conn_id_len, source_conn_id_len;
1844
1845
  /* RFC 8999 6 */
1846
1847
  /* First byte + version (4) + 2 CID lengths (set to 0) + at least one supported version */
1848
0
  if(packet->payload_packet_len < 11) {
1849
0
    return 0;
1850
0
  }
1851
1852
0
  first_byte = packet->payload[0];
1853
0
  pub_bit1 = ((first_byte & 0x80) != 0);
1854
0
  if(!pub_bit1) {
1855
0
    NDPI_LOG_DBG2(ndpi_struct, "Not a long header\n");
1856
0
    return 0;
1857
0
  }
1858
1859
0
  version = ntohl(*((u_int32_t *)&packet->payload[1]));
1860
0
  if(version != 0) {
1861
0
    NDPI_LOG_DBG2(ndpi_struct, "Invalid version 0x%x\n", version);
1862
0
    return 0;
1863
0
  }
1864
1865
  /* Check that CIDs lengths are valid: QUIC limits the CID length to 20 */
1866
0
  dest_conn_id_len = packet->payload[5];
1867
0
  if(5 + 1 + dest_conn_id_len >= packet->payload_packet_len) {
1868
0
    NDPI_LOG_DBG2(ndpi_struct, "Invalid Length %d\n", packet->payload_packet_len);
1869
0
    return 0;
1870
0
  }
1871
0
  source_conn_id_len = packet->payload[5 + 1 + dest_conn_id_len];
1872
0
  if (dest_conn_id_len > QUIC_MAX_CID_LENGTH ||
1873
0
      source_conn_id_len > QUIC_MAX_CID_LENGTH) {
1874
0
    NDPI_LOG_DBG2(ndpi_struct, "Invalid CIDs length %u %u",
1875
0
      dest_conn_id_len, source_conn_id_len);
1876
0
    return 0;
1877
0
  }
1878
1879
0
  return 1;
1880
0
}
1881
1882
static int ndpi_search_quic_extra_vn(struct ndpi_detection_module_struct *ndpi_struct,
1883
             struct ndpi_flow_struct *flow)
1884
0
{
1885
0
  struct ndpi_packet_struct *packet = &ndpi_struct->packet;
1886
1887
  /* We are elaborating a packet following the Forcing VN, i.e. we are expecting:
1888
     1) first a VN packet (from the server)
1889
     2) then a "standard" Initial from the client */
1890
  /* TODO: could we unify ndpi_search_quic() and ndpi_search_quic_extra_vn() somehow? */
1891
1892
0
  NDPI_LOG_DBG(ndpi_struct, "search QUIC extra func VN\n");
1893
1894
0
  if(packet->payload_packet_len == 0)
1895
0
    return 1; /* Keep going */
1896
1897
0
  if(flow->l4.udp.quic_vn_pair == 0) {
1898
0
    if(is_vn(ndpi_struct)) {
1899
0
      NDPI_LOG_DBG(ndpi_struct, "Valid VN\n");
1900
0
      flow->l4.udp.quic_vn_pair = 1;
1901
0
      return 1;
1902
0
    } else {
1903
0
      NDPI_LOG_DBG(ndpi_struct, "Invalid reply to a Force VN. Stop\n");
1904
0
      flow->extra_packets_func = NULL;
1905
0
      return 0; /* Stop */
1906
0
    }
1907
0
  } else {
1908
0
    flow->extra_packets_func = NULL;
1909
0
    ndpi_search_quic(ndpi_struct, flow);
1910
0
    return 0;
1911
0
  }
1912
0
}
1913
1914
static void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct,
1915
           struct ndpi_flow_struct *flow)
1916
0
{
1917
0
  u_int32_t version;
1918
0
  u_int8_t *clear_payload;
1919
0
  uint32_t clear_payload_len = 0;
1920
0
  const u_int8_t *crypto_data;
1921
0
  uint64_t crypto_data_len;
1922
0
  int is_initial_quic, ret;
1923
1924
0
  NDPI_LOG_DBG2(ndpi_struct, "search QUIC\n");
1925
1926
  /* Buffers: packet->payload ---> clear_payload ---> crypto_data */
1927
1928
  /*
1929
   * 1) (Very) basic heuristic to check if it is a QUIC packet.
1930
   *    The first packet of each QUIC session should contain a valid
1931
   *    CHLO/ClientHello message and we need (only) it to sub-classify
1932
   *    the flow.
1933
   *    Detecting QUIC sessions where the first captured packet is not a
1934
   *    CHLO/CH is VERY hard. Let try only some easy cases:
1935
   *    * out-of-order 0-RTT, i.e 0-RTT packets received before the Initial;
1936
   *      in that case, keep looking for the Initial
1937
   *    * if we have only SH pkts, focus on standard case where server
1938
   *      port is 443 and default length of Server CID is >=8 (as it happens
1939
   *      with most common broswer and apps). Look for 3 consecutive SH
1940
   *      pkts send by the client and check their CIDs (note that
1941
   *      some QUIC implementations have Client CID length set to 0, so
1942
   *      checking pkts sent by server is useless). Since we don't know the
1943
   *      real CID length, use the min value 8, i.e. QUIC_SERVER_CID_HEURISTIC_LENGTH
1944
   *    * with only GQUIC packets from server (usefull with unidirectional
1945
   *      captures) look for Rejection packet
1946
   *    Avoid the generic cases and let's see if anyone complains...
1947
   */
1948
1949
0
  is_initial_quic = may_be_initial_pkt(ndpi_struct, &version);
1950
0
  if(!is_initial_quic) {
1951
0
    if(!is_ch_reassembler_pending(flow)) { /* Better safe than sorry */
1952
0
      ret = may_be_0rtt(ndpi_struct, &version);
1953
0
      if(ret == 1) {
1954
0
        NDPI_LOG_DBG(ndpi_struct, "Found 0-RTT, keep looking for Initial\n");
1955
0
        flow->l4.udp.quic_0rtt_found = 1;
1956
0
        if(flow->packet_counter >= 3) {
1957
          /* We haven't still found an Initial.. give up */
1958
0
          NDPI_LOG_INFO(ndpi_struct, "QUIC 0RTT\n");
1959
0
          ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
1960
0
          flow->protos.tls_quic.quic_version = version;
1961
0
        }
1962
0
        return;
1963
0
      } else if(flow->l4.udp.quic_0rtt_found == 1) {
1964
        /* Unknown packet (probably an Handshake one) after a 0-RTT */
1965
0
        NDPI_LOG_INFO(ndpi_struct, "QUIC 0RTT (without Initial)\n");
1966
0
        ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
1967
0
        flow->protos.tls_quic.quic_version = 0; /* unknown */
1968
0
        return;
1969
0
      }
1970
0
      ret = may_be_sh(ndpi_struct, flow);
1971
0
      if(ret == 1) {
1972
0
        NDPI_LOG_INFO(ndpi_struct, "SH Quic\n");
1973
0
        ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
1974
0
        flow->protos.tls_quic.quic_version = 0; /* unknown */
1975
0
  return;
1976
0
      }
1977
0
      if(ret == -1) {
1978
0
        NDPI_LOG_DBG2(ndpi_struct, "Keep looking for SH by client\n");
1979
0
        if(flow->packet_counter > 10 /* TODO */)
1980
0
          NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
1981
0
  return;
1982
0
      }
1983
0
      ret = may_be_gquic_rej(ndpi_struct);
1984
0
      if(ret == 1) {
1985
0
        NDPI_LOG_INFO(ndpi_struct, "GQUIC REJ\n");
1986
0
        ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
1987
0
        flow->protos.tls_quic.quic_version = 0; /* unknown */
1988
0
  return;
1989
0
      }
1990
0
    }
1991
0
    NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
1992
0
    return;
1993
0
  }
1994
1995
  /*
1996
   * 2) Ok, this packet seems to be QUIC
1997
   */
1998
1999
0
  NDPI_LOG_INFO(ndpi_struct, "found QUIC\n");
2000
0
  ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, NDPI_PROTOCOL_UNKNOWN, NDPI_CONFIDENCE_DPI);
2001
0
  flow->protos.tls_quic.quic_version = version;
2002
2003
  /*
2004
   * 3) Skip not supported versions
2005
   */
2006
2007
0
  if(!is_version_supported(version)) {
2008
0
    NDPI_LOG_DBG(ndpi_struct, "Unsupported version 0x%x\n", version);
2009
0
    NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
2010
0
    return;
2011
0
  }
2012
2013
  /*
2014
   * 3a) Forcing VN. There is no payload to analyze yet.
2015
   * Expecteed flow:
2016
   *  *) C->S: Forcing VN
2017
   *  *) S->C: VN
2018
   *  *) C->S: "Standard" Initial with crypto data
2019
   */
2020
0
  if(is_version_forcing_vn(version)) {
2021
0
    NDPI_LOG_DBG(ndpi_struct, "Forcing VN\n");
2022
0
    flow->max_extra_packets_to_check = 4; /* TODO */
2023
0
    flow->extra_packets_func = ndpi_search_quic_extra_vn;
2024
0
    return;
2025
0
  }
2026
2027
  /*
2028
   * 4) Extract the Payload from Initial Packets
2029
   */
2030
0
  clear_payload = get_clear_payload(ndpi_struct, flow, version, &clear_payload_len);
2031
0
  if(!clear_payload) {
2032
0
    NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
2033
0
    return;
2034
0
  }
2035
2036
  /*
2037
   * 5) Extract Crypto Data from the Payload
2038
   */
2039
0
  crypto_data = get_crypto_data(ndpi_struct, flow,
2040
0
        clear_payload, clear_payload_len,
2041
0
        &crypto_data_len);
2042
2043
  /*
2044
   * 6) Process ClientHello/CHLO from the Crypto Data (if any)
2045
   */
2046
0
  if(crypto_data) {
2047
0
    if(!is_version_with_tls(version)) {
2048
0
      process_chlo(ndpi_struct, flow, crypto_data, crypto_data_len);
2049
0
    } else {
2050
0
      process_tls(ndpi_struct, flow, crypto_data, crypto_data_len);
2051
0
    }
2052
0
  }
2053
0
  if(is_version_with_encrypted_header(version)) {
2054
0
    ndpi_free(clear_payload);
2055
0
  }
2056
2057
  /*
2058
   * 7) We need to process other packets than (the first) ClientHello/CHLO?
2059
   */
2060
0
  if(eval_extra_processing(ndpi_struct, flow)) {
2061
0
    flow->max_extra_packets_to_check = 24; /* TODO */
2062
0
    flow->extra_packets_func = ndpi_search_quic_extra;
2063
0
  } else if(!crypto_data) {
2064
0
    NDPI_EXCLUDE_DISSECTOR(ndpi_struct, flow);
2065
0
  }
2066
0
}
2067
2068
/* ***************************************************************** */
2069
2070
void init_quic_dissector(struct ndpi_detection_module_struct *ndpi_struct)
2071
1
{
2072
1
  ndpi_register_dissector("QUIC", ndpi_struct,
2073
1
                     ndpi_search_quic,
2074
1
                     NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD,
2075
1
                     1, NDPI_PROTOCOL_QUIC);
2076
1
}