dot11decrypt: Support 384 bit long PMK

With AKMS 00-0F-AC:12 a 384 bit long PMK shall be used. To be able
to support key derivation and decryption from this larger sized
PMK the user PSK / PMK key input validation code is updated as well
as the various places where a hard coded PMK size is used.

Ping-Bug: 16197
Change-Id: I39c9337e8a84095246e3db5ef33dc96fb78e5dc3
Reviewed-on: https://code.wireshark.org/review/35065
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Mikael Kanstrup 2019-11-10 09:07:48 +01:00 committed by Anders Broman
parent 7638ea013d
commit 5915613879
4 changed files with 20 additions and 22 deletions

View File

@ -237,7 +237,7 @@ static const UCHAR * Dot11DecryptGetBssidAddress(
static void
Dot11DecryptDerivePtk(
DOT11DECRYPT_SEC_ASSOCIATION *sa,
const UCHAR pmk[32],
const UCHAR *pmk,
const UCHAR snonce[32],
int key_version,
int akm,
@ -246,7 +246,7 @@ Dot11DecryptDerivePtk(
static void
Dot11DecryptRsnaPrfX(
DOT11DECRYPT_SEC_ASSOCIATION *sa,
const UCHAR pmk[32],
const UCHAR *pmk,
const UCHAR snonce[32],
const INT x, /* for TKIP 512, for CCMP 384 */
UCHAR *ptk,
@ -255,7 +255,7 @@ Dot11DecryptRsnaPrfX(
static void
Dot11DecryptRsnaKdfX(
DOT11DECRYPT_SEC_ASSOCIATION *sa,
const UCHAR pmk[32],
const UCHAR *pmk,
const UCHAR snonce[32],
const INT x,
UCHAR *ptk,
@ -304,7 +304,7 @@ const guint8 broadcast_mac[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
typedef void (*DOT11DECRYPT_PTK_DERIVE_FUNC)(
DOT11DECRYPT_SEC_ASSOCIATION *sa,
const UCHAR pmk[32],
const UCHAR *pmk,
const UCHAR snonce[32],
const INT x,
UCHAR *ptk,
@ -966,6 +966,7 @@ INT Dot11DecryptSetKeys(
if (keys[i].KeyType==DOT11DECRYPT_KEY_TYPE_WPA_PWD) {
DEBUG_PRINT_LINE("Set a WPA-PWD key", DEBUG_LEVEL_4);
Dot11DecryptRsnaPwd2Psk(keys[i].UserPwd.Passphrase, keys[i].UserPwd.Ssid, keys[i].UserPwd.SsidLen, keys[i].KeyData.Wpa.Psk);
keys[i].KeyData.Wpa.PskLen = DOT11DECRYPT_WPA_PWD_PSK_LEN;
}
#ifdef DOT11DECRYPT_DEBUG
else if (keys[i].KeyType==DOT11DECRYPT_KEY_TYPE_WPA_PMK) {
@ -2116,7 +2117,7 @@ Dot11DecryptGetDeriveAlgoFromAkm(int akm)
static void
Dot11DecryptDerivePtk(
DOT11DECRYPT_SEC_ASSOCIATION *sa,
const UCHAR pmk[32],
const UCHAR *pmk,
const UCHAR snonce[32],
int key_version,
int akm,
@ -2162,7 +2163,7 @@ Dot11DecryptDerivePtk(
static void
Dot11DecryptRsnaPrfX(
DOT11DECRYPT_SEC_ASSOCIATION *sa,
const UCHAR pmk[32],
const UCHAR *pmk,
const UCHAR snonce[32],
const INT x, /* for TKIP 512, for CCMP 384 */
UCHAR *ptk,
@ -2220,7 +2221,7 @@ Dot11DecryptRsnaPrfX(
static void
Dot11DecryptRsnaKdfX(
DOT11DECRYPT_SEC_ASSOCIATION *sa,
const UCHAR pmk[32],
const UCHAR *pmk,
const UCHAR snonce[32],
const INT x,
UCHAR *ptk,
@ -2350,7 +2351,7 @@ Dot11DecryptRsnaPwd2Psk(
Dot11DecryptRsnaPwd2PskStep(pp_ba->data, pp_ba->len, ssid, ssidLength, 4096, 1, m_output);
Dot11DecryptRsnaPwd2PskStep(pp_ba->data, pp_ba->len, ssid, ssidLength, 4096, 2, &m_output[20]);
memcpy(output, m_output, DOT11DECRYPT_WPA_PSK_LEN);
memcpy(output, m_output, DOT11DECRYPT_WPA_PWD_PSK_LEN);
g_byte_array_free(pp_ba, TRUE);
return 0;
@ -2513,7 +2514,8 @@ parse_key_string(gchar* input_string, guint8 key_type)
res = hex_str_to_bytes(input_string, key_ba, FALSE);
/* Two tokens means that the user should have entered a WPA-BIN key ... */
if(!res || ((key_ba->len) != WPA_PSK_KEY_SIZE))
if(!res || (key_ba->len != DOT11DECRYPT_WPA_PWD_PSK_LEN &&
key_ba->len != DOT11DECRYPT_WPA_PMK_MAX_LEN))
{
g_byte_array_free(key_ba, TRUE);

View File

@ -43,7 +43,8 @@
#define DOT11DECRYPT_WPA_PASSPHRASE_MAX_LEN 63 /* null-terminated string, the actual length of the storage is 64 */
#define DOT11DECRYPT_WPA_SSID_MIN_LEN 0
#define DOT11DECRYPT_WPA_SSID_MAX_LEN 32
#define DOT11DECRYPT_WPA_PSK_LEN 32
#define DOT11DECRYPT_WPA_PMK_MAX_LEN 48
#define DOT11DECRYPT_WPA_PWD_PSK_LEN 32
/* */
/* */
/******************************************************************************/
@ -124,8 +125,9 @@ typedef struct _DOT11DECRYPT_KEY_ITEM {
* calculated.
*/
struct DOT11DECRYPT_KEY_ITEMDATA_WPA {
UCHAR Psk[DOT11DECRYPT_WPA_PSK_LEN];
UCHAR Psk[DOT11DECRYPT_WPA_PMK_MAX_LEN];
UCHAR Ptk[DOT11DECRYPT_WPA_PTK_MAX_LEN];
UINT8 PskLen;
UINT8 PtkLen;
UINT8 Akm;
UINT8 Cipher;

View File

@ -66,13 +66,6 @@ extern "C" {
#define WPA_SSID_MIN_CHAR_SIZE 0
#define WPA_SSID_MIN_BIT_SIZE (WPA_SSID_MIN_CHAR_SIZE*8)
/**
* Let the user enter a raw PSK along with a passphrase + SSID
*/
#define WPA_PSK_KEY_SIZE 32 /* Fixed size, 32 bytes (256bit) */
#define WPA_PSK_KEY_CHAR_SIZE (WPA_PSK_KEY_SIZE*2)
#define WPA_PSK_KEY_BIT_SIZE (WPA_PSK_KEY_SIZE*8)
/**
* Prefix definitions for preferences
*/

View File

@ -25045,8 +25045,8 @@ dissect_ieee80211_common(tvbuff_t *tvb, packet_info *pinfo,
proto_item_set_generated(ti);
/* Also add the PMK used to to decrypt the packet. (PMK==PSK) */
bytes_to_hexstr(out_buff, used_key.KeyData.Wpa.Psk, DOT11DECRYPT_WPA_PSK_LEN); /* 32 bytes */
out_buff[2*DOT11DECRYPT_WPA_PSK_LEN] = '\0';
bytes_to_hexstr(out_buff, used_key.KeyData.Wpa.Psk, used_key.KeyData.Wpa.PskLen);
out_buff[2*used_key.KeyData.Wpa.PskLen] = '\0';
ti = proto_tree_add_string(wep_tree, hf_ieee80211_fc_analysis_pmk, tvb, 0, 0, out_buff);
proto_item_set_generated(ti);
@ -26155,9 +26155,10 @@ set_dot11decrypt_keys(void)
hex_str_to_bytes(dk->key->str, bytes, FALSE);
/* XXX - Pass the correct array of bytes... */
if (bytes->len <= DOT11DECRYPT_WPA_PSK_LEN) {
if (bytes->len <= DOT11DECRYPT_WPA_PWD_PSK_LEN ||
bytes->len == DOT11DECRYPT_WPA_PMK_MAX_LEN) {
memcpy(key.KeyData.Wpa.Psk, bytes->data, bytes->len);
key.KeyData.Wpa.PskLen = bytes->len;
keys->Keys[keys->nKeys] = key;
keys->nKeys += 1;
}