/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 | } |