Coverage Report

Created: 2025-02-15 06:25

/src/wireshark/epan/crypt/dot11decrypt_gcmp.c
Line
Count
Source (jump to first uncovered line)
1
/* dot11decrypt_gcmp.c
2
 *
3
 * Wireshark - Network traffic analyzer
4
 * By Gerald Combs <gerald@wireshark.org>
5
 * Copyright 1998 Gerald Combs
6
 *
7
 * SPDX-License-Identifier: GPL-2.0-or-later
8
 */
9
10
/****************************************************************************/
11
/* File includes                */
12
#include "config.h"
13
14
#include "dot11decrypt_debug.h"
15
#include "dot11decrypt_int.h"
16
#include "dot11decrypt_system.h"
17
#include "dot11decrypt_util.h"
18
19
#include <wsutil/wsgcrypt.h>
20
21
/****************************************************************************/
22
/*  Internal definitions              */
23
24
/****************************************************************************/
25
/* Internal macros                */
26
27
#define READ_6(b0, b1, b2, b3, b4, b5) \
28
0
  ((((uint64_t)((uint16_t)((b4 << 0) | (b5 << 8)))) << 32) | \
29
0
      ((uint32_t)((b0 << 0) | (b1 << 8) | (b2 << 16) | (b3 << 24))))
30
31
/****************************************************************************/
32
/* Internal function prototypes declarations          */
33
34
/****************************************************************************/
35
/* Function definitions             */
36
37
/* From IEEE 802.11 2016 Chapter 12.5.5.3.4 Construct GCM nonce */
38
static void
39
gcmp_construct_nonce(
40
  PDOT11DECRYPT_MAC_FRAME wh,
41
  uint64_t pn,
42
  uint8_t nonce[12])
43
0
{
44
  /* Nonce: A2 | PN */
45
0
  DOT11DECRYPT_ADDR_COPY(nonce, wh->addr2);
46
0
  nonce[6] = (uint8_t)(pn >> 40);
47
0
  nonce[7] = (uint8_t)(pn >> 32);
48
0
  nonce[8] = (uint8_t)(pn >> 24);
49
0
  nonce[9] = (uint8_t)(pn >> 16);
50
0
  nonce[10] = (uint8_t)(pn >> 8);
51
0
  nonce[11] = (uint8_t)(pn >> 0);
52
0
}
53
54
int Dot11DecryptGcmpDecrypt(
55
  uint8_t *m,
56
  int mac_header_len,
57
  int len,
58
  uint8_t *TK1,
59
  int tk_len)
60
0
{
61
0
  PDOT11DECRYPT_MAC_FRAME wh;
62
0
  uint8_t aad[30];
63
0
  uint8_t nonce[12];
64
0
  uint8_t mic[16];
65
0
  ssize_t data_len;
66
0
  size_t aad_len;
67
0
  int z = mac_header_len;
68
0
  gcry_cipher_hd_t handle;
69
0
  uint64_t pn;
70
0
  uint8_t *ivp = m + z;
71
72
0
  wh = (PDOT11DECRYPT_MAC_FRAME )m;
73
0
  data_len = len - (z + DOT11DECRYPT_GCMP_HEADER + sizeof(mic));
74
0
  if (data_len < 1) {
75
0
    return 0;
76
0
  }
77
78
0
  memcpy(mic, m + len - sizeof(mic), sizeof(mic));
79
0
  pn = READ_6(ivp[0], ivp[1], ivp[4], ivp[5], ivp[6], ivp[7]);
80
0
  gcmp_construct_nonce(wh, pn, nonce);
81
0
  dot11decrypt_construct_aad(wh, aad, &aad_len);
82
83
0
  if (gcry_cipher_open(&handle, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_GCM, 0)) {
84
0
    return 1;
85
0
  }
86
0
  if (gcry_cipher_setkey(handle, TK1, tk_len)) {
87
0
    goto err_out;
88
0
  }
89
0
  if (gcry_cipher_setiv(handle, nonce, sizeof(nonce))) {
90
0
    goto err_out;
91
0
  }
92
0
  if (gcry_cipher_authenticate(handle, aad, aad_len)) {
93
0
    goto err_out;
94
0
  }
95
0
  if (gcry_cipher_decrypt(handle, m + z + DOT11DECRYPT_GCMP_HEADER, data_len, NULL, 0)) {
96
0
    goto err_out;
97
0
  }
98
0
  if (gcry_cipher_checktag(handle, mic, sizeof(mic))) {
99
0
    goto err_out;
100
0
  }
101
102
  /* TODO replay check  (IEEE 802.11i-2004, pg. 62)     */
103
  /* TODO PN must be incremental (IEEE 802.11i-2004, pg. 62)    */
104
105
0
  gcry_cipher_close(handle);
106
0
  return 0;
107
0
err_out:
108
0
  gcry_cipher_close(handle);
109
0
  return 1;
110
0
}