// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright 2002 - 2004 , Instant802 Networks , Inc .
* Copyright 2005 , Devicescape Software , Inc .
* Copyright ( C ) 2016 Intel Deutschland GmbH
*/
#include <linux/kernel.h>
#include <linux/bitops.h>
#include <linux/types.h>
#include <linux/netdevice.h>
#include <linux/export.h>
#include <linux/unaligned.h>
#include <net/mac80211.h>
#include "driver-ops.h"
#include "key.h"
#include "tkip.h"
#include "wep.h"
#define PHASE1_LOOP_COUNT 8
/*
* 2 - byte by 2 - byte subset of the full AES S - box table ; second part of this
* table is identical to first part but byte - swapped
*/
static const u16 tkip_sbox[256 ] =
{
0 xC6A5, 0 xF884, 0 xEE99, 0 xF68D, 0 xFF0D, 0 xD6BD, 0 xDEB1, 0 x9154,
0 x6050, 0 x0203, 0 xCEA9, 0 x567D, 0 xE719, 0 xB562, 0 x4DE6, 0 xEC9A,
0 x8F45, 0 x1F9D, 0 x8940, 0 xFA87, 0 xEF15, 0 xB2EB, 0 x8EC9, 0 xFB0B,
0 x41EC, 0 xB367, 0 x5FFD, 0 x45EA, 0 x23BF, 0 x53F7, 0 xE496, 0 x9B5B,
0 x75C2, 0 xE11C, 0 x3DAE, 0 x4C6A, 0 x6C5A, 0 x7E41, 0 xF502, 0 x834F,
0 x685C, 0 x51F4, 0 xD134, 0 xF908, 0 xE293, 0 xAB73, 0 x6253, 0 x2A3F,
0 x080C, 0 x9552, 0 x4665, 0 x9D5E, 0 x3028, 0 x37A1, 0 x0A0F, 0 x2FB5,
0 x0E09, 0 x2436, 0 x1B9B, 0 xDF3D, 0 xCD26, 0 x4E69, 0 x7FCD, 0 xEA9F,
0 x121B, 0 x1D9E, 0 x5874, 0 x342E, 0 x362D, 0 xDCB2, 0 xB4EE, 0 x5BFB,
0 xA4F6, 0 x764D, 0 xB761, 0 x7DCE, 0 x527B, 0 xDD3E, 0 x5E71, 0 x1397,
0 xA6F5, 0 xB968, 0 x0000, 0 xC12C, 0 x4060, 0 xE31F, 0 x79C8, 0 xB6ED,
0 xD4BE, 0 x8D46, 0 x67D9, 0 x724B, 0 x94DE, 0 x98D4, 0 xB0E8, 0 x854A,
0 xBB6B, 0 xC52A, 0 x4FE5, 0 xED16, 0 x86C5, 0 x9AD7, 0 x6655, 0 x1194,
0 x8ACF, 0 xE910, 0 x0406, 0 xFE81, 0 xA0F0, 0 x7844, 0 x25BA, 0 x4BE3,
0 xA2F3, 0 x5DFE, 0 x80C0, 0 x058A, 0 x3FAD, 0 x21BC, 0 x7048, 0 xF104,
0 x63DF, 0 x77C1, 0 xAF75, 0 x4263, 0 x2030, 0 xE51A, 0 xFD0E, 0 xBF6D,
0 x814C, 0 x1814, 0 x2635, 0 xC32F, 0 xBEE1, 0 x35A2, 0 x88CC, 0 x2E39,
0 x9357, 0 x55F2, 0 xFC82, 0 x7A47, 0 xC8AC, 0 xBAE7, 0 x322B, 0 xE695,
0 xC0A0, 0 x1998, 0 x9ED1, 0 xA37F, 0 x4466, 0 x547E, 0 x3BAB, 0 x0B83,
0 x8CCA, 0 xC729, 0 x6BD3, 0 x283C, 0 xA779, 0 xBCE2, 0 x161D, 0 xAD76,
0 xDB3B, 0 x6456, 0 x744E, 0 x141E, 0 x92DB, 0 x0C0A, 0 x486C, 0 xB8E4,
0 x9F5D, 0 xBD6E, 0 x43EF, 0 xC4A6, 0 x39A8, 0 x31A4, 0 xD337, 0 xF28B,
0 xD532, 0 x8B43, 0 x6E59, 0 xDAB7, 0 x018C, 0 xB164, 0 x9CD2, 0 x49E0,
0 xD8B4, 0 xACFA, 0 xF307, 0 xCF25, 0 xCAAF, 0 xF48E, 0 x47E9, 0 x1018,
0 x6FD5, 0 xF088, 0 x4A6F, 0 x5C72, 0 x3824, 0 x57F1, 0 x73C7, 0 x9751,
0 xCB23, 0 xA17C, 0 xE89C, 0 x3E21, 0 x96DD, 0 x61DC, 0 x0D86, 0 x0F85,
0 xE090, 0 x7C42, 0 x71C4, 0 xCCAA, 0 x90D8, 0 x0605, 0 xF701, 0 x1C12,
0 xC2A3, 0 x6A5F, 0 xAEF9, 0 x69D0, 0 x1791, 0 x9958, 0 x3A27, 0 x27B9,
0 xD938, 0 xEB13, 0 x2BB3, 0 x2233, 0 xD2BB, 0 xA970, 0 x0789, 0 x33A7,
0 x2DB6, 0 x3C22, 0 x1592, 0 xC920, 0 x8749, 0 xAAFF, 0 x5078, 0 xA57A,
0 x038F, 0 x59F8, 0 x0980, 0 x1A17, 0 x65DA, 0 xD731, 0 x84C6, 0 xD0B8,
0 x82C3, 0 x29B0, 0 x5A77, 0 x1E11, 0 x7BCB, 0 xA8FC, 0 x6DD6, 0 x2C3A,
};
static u16 tkipS(u16 val)
{
return tkip_sbox[val & 0 xff] ^ swab16(tkip_sbox[val >> 8 ]);
}
static u8 *write_tkip_iv(u8 *pos, u16 iv16)
{
*pos++ = iv16 >> 8 ;
*pos++ = ((iv16 >> 8 ) | 0 x20) & 0 x7f;
*pos++ = iv16 & 0 xFF;
return pos;
}
/*
* P1K : = Phase1 ( TA , TK , TSC )
* TA = transmitter address ( 48 bits )
* TK = dot11DefaultKeyValue or dot11KeyMappingValue ( 128 bits )
* TSC = TKIP sequence counter ( 48 bits , only 32 msb bits used )
* P1K : 80 bits
*/
static void tkip_mixing_phase1(const u8 *tk, struct tkip_ctx *ctx,
const u8 *ta, u32 tsc_IV32)
{
int i, j;
u16 *p1k = ctx->p1k;
p1k[0 ] = tsc_IV32 & 0 xFFFF;
p1k[1 ] = tsc_IV32 >> 16 ;
p1k[2 ] = get_unaligned_le16(ta + 0 );
p1k[3 ] = get_unaligned_le16(ta + 2 );
p1k[4 ] = get_unaligned_le16(ta + 4 );
for (i = 0 ; i < PHASE1_LOOP_COUNT; i++) {
j = 2 * (i & 1 );
p1k[0 ] += tkipS(p1k[4 ] ^ get_unaligned_le16(tk + 0 + j));
p1k[1 ] += tkipS(p1k[0 ] ^ get_unaligned_le16(tk + 4 + j));
p1k[2 ] += tkipS(p1k[1 ] ^ get_unaligned_le16(tk + 8 + j));
p1k[3 ] += tkipS(p1k[2 ] ^ get_unaligned_le16(tk + 12 + j));
p1k[4 ] += tkipS(p1k[3 ] ^ get_unaligned_le16(tk + 0 + j)) + i;
}
ctx->state = TKIP_STATE_PHASE1_DONE;
ctx->p1k_iv32 = tsc_IV32;
}
static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx,
u16 tsc_IV16, u8 *rc4key)
{
u16 ppk[6 ];
const u16 *p1k = ctx->p1k;
int i;
ppk[0 ] = p1k[0 ];
ppk[1 ] = p1k[1 ];
ppk[2 ] = p1k[2 ];
ppk[3 ] = p1k[3 ];
ppk[4 ] = p1k[4 ];
ppk[5 ] = p1k[4 ] + tsc_IV16;
ppk[0 ] += tkipS(ppk[5 ] ^ get_unaligned_le16(tk + 0 ));
ppk[1 ] += tkipS(ppk[0 ] ^ get_unaligned_le16(tk + 2 ));
ppk[2 ] += tkipS(ppk[1 ] ^ get_unaligned_le16(tk + 4 ));
ppk[3 ] += tkipS(ppk[2 ] ^ get_unaligned_le16(tk + 6 ));
ppk[4 ] += tkipS(ppk[3 ] ^ get_unaligned_le16(tk + 8 ));
ppk[5 ] += tkipS(ppk[4 ] ^ get_unaligned_le16(tk + 10 ));
ppk[0 ] += ror16(ppk[5 ] ^ get_unaligned_le16(tk + 12 ), 1 );
ppk[1 ] += ror16(ppk[0 ] ^ get_unaligned_le16(tk + 14 ), 1 );
ppk[2 ] += ror16(ppk[1 ], 1 );
ppk[3 ] += ror16(ppk[2 ], 1 );
ppk[4 ] += ror16(ppk[3 ], 1 );
ppk[5 ] += ror16(ppk[4 ], 1 );
rc4key = write_tkip_iv(rc4key, tsc_IV16);
*rc4key++ = ((ppk[5 ] ^ get_unaligned_le16(tk)) >> 1 ) & 0 xFF;
for (i = 0 ; i < 6 ; i++)
put_unaligned_le16(ppk[i], rc4key + 2 * i);
}
/* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets
* of the IV . Returns pointer to the octet following IVs ( i . e . , beginning of
* the packet payload). */
u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key_conf *keyconf, u64 pn)
{
pos = write_tkip_iv(pos, TKIP_PN_TO_IV16(pn));
*pos++ = (keyconf->keyidx << 6 ) | (1 << 5 ) /* Ext IV */;
put_unaligned_le32(TKIP_PN_TO_IV32(pn), pos);
return pos + 4 ;
}
EXPORT_SYMBOL_GPL(ieee80211_tkip_add_iv);
static void ieee80211_compute_tkip_p1k(struct ieee80211_key *key, u32 iv32)
{
struct ieee80211_sub_if_data *sdata = key->sdata;
struct tkip_ctx *ctx = &key->u.tkip.tx;
const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
lockdep_assert_held(&key->u.tkip.txlock);
/*
* Update the P1K when the IV32 is different from the value it
* had when we last computed it ( or when not initialised yet ) .
* This might flip - flop back and forth if packets are processed
* out - of - order due to the different ACs , but then we have to
* just compute the P1K more often .
*/
if (ctx->p1k_iv32 != iv32 || ctx->state == TKIP_STATE_NOT_INIT)
tkip_mixing_phase1(tk, ctx, sdata->vif.addr, iv32);
}
void ieee80211_get_tkip_p1k_iv(struct ieee80211_key_conf *keyconf,
u32 iv32, u16 *p1k)
{
struct ieee80211_key *key = (struct ieee80211_key *)
container_of(keyconf, struct ieee80211_key, conf);
struct tkip_ctx *ctx = &key->u.tkip.tx;
spin_lock_bh(&key->u.tkip.txlock);
ieee80211_compute_tkip_p1k(key, iv32);
memcpy(p1k, ctx->p1k, sizeof (ctx->p1k));
spin_unlock_bh(&key->u.tkip.txlock);
}
EXPORT_SYMBOL(ieee80211_get_tkip_p1k_iv);
void ieee80211_get_tkip_rx_p1k(struct ieee80211_key_conf *keyconf,
const u8 *ta, u32 iv32, u16 *p1k)
{
const u8 *tk = &keyconf->key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
struct tkip_ctx ctx;
tkip_mixing_phase1(tk, &ctx, ta, iv32);
memcpy(p1k, ctx.p1k, sizeof (ctx.p1k));
}
EXPORT_SYMBOL(ieee80211_get_tkip_rx_p1k);
void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf,
struct sk_buff *skb, u8 *p2k)
{
struct ieee80211_key *key = (struct ieee80211_key *)
container_of(keyconf, struct ieee80211_key, conf);
const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
struct tkip_ctx *ctx = &key->u.tkip.tx;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
const u8 *data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control);
u32 iv32 = get_unaligned_le32(&data[4 ]);
u16 iv16 = data[2 ] | (data[0 ] << 8 );
spin_lock(&key->u.tkip.txlock);
ieee80211_compute_tkip_p1k(key, iv32);
tkip_mixing_phase2(tk, ctx, iv16, p2k);
spin_unlock(&key->u.tkip.txlock);
}
EXPORT_SYMBOL(ieee80211_get_tkip_p2k);
/*
* Encrypt packet payload with TKIP using @ key . @ pos is a pointer to the
* beginning of the buffer containing payload . This payload must include
* the IV / Ext . IV and space for ( taildroom ) four octets for ICV .
* @ payload_len is the length of payload ( _ not_ including IV / ICV length ) .
* @ ta is the transmitter addresses .
*/
int ieee80211_tkip_encrypt_data(struct arc4_ctx *ctx,
struct ieee80211_key *key,
struct sk_buff *skb,
u8 *payload, size_t payload_len)
{
u8 rc4key[16 ];
ieee80211_get_tkip_p2k(&key->conf, skb, rc4key);
return ieee80211_wep_encrypt_data(ctx, rc4key, 16 ,
payload, payload_len);
}
/* Decrypt packet payload with TKIP using @key. @pos is a pointer to the
* beginning of the buffer containing IEEE 802 . 11 header payload , i . e . ,
* including IV , Ext . IV , real data , Michael MIC , ICV . @ payload_len is the
* length of payload, including IV, Ext. IV, MIC, ICV. */
int ieee80211_tkip_decrypt_data(struct arc4_ctx *ctx,
struct ieee80211_key *key,
u8 *payload, size_t payload_len, u8 *ta,
u8 *ra, int only_iv, int queue,
u32 *out_iv32, u16 *out_iv16)
{
u32 iv32;
u32 iv16;
u8 rc4key[16 ], keyid, *pos = payload;
int res;
const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
struct tkip_ctx_rx *rx_ctx = &key->u.tkip.rx[queue];
if (payload_len < 12 )
return -1 ;
iv16 = (pos[0 ] << 8 ) | pos[2 ];
keyid = pos[3 ];
iv32 = get_unaligned_le32(pos + 4 );
pos += 8 ;
if (!(keyid & (1 << 5 )))
return TKIP_DECRYPT_NO_EXT_IV;
if ((keyid >> 6 ) != key->conf.keyidx)
return TKIP_DECRYPT_INVALID_KEYIDX;
/* Reject replays if the received TSC is smaller than or equal to the
* last received value in a valid message , but with an exception for
* the case where a new key has been set and no valid frame using that
* key has yet received and the local RSC was initialized to 0 . This
* exception allows the very first frame sent by the transmitter to be
* accepted even if that transmitter were to use TSC 0 ( IEEE 802 . 11
* described TSC to be initialized to 1 whenever a new key is taken into
* use ) .
*/
if (iv32 < rx_ctx->iv32 ||
(iv32 == rx_ctx->iv32 &&
(iv16 < rx_ctx->iv16 ||
(iv16 == rx_ctx->iv16 &&
(rx_ctx->iv32 || rx_ctx->iv16 ||
rx_ctx->ctx.state != TKIP_STATE_NOT_INIT)))))
return TKIP_DECRYPT_REPLAY;
if (only_iv) {
res = TKIP_DECRYPT_OK;
rx_ctx->ctx.state = TKIP_STATE_PHASE1_HW_UPLOADED;
goto done;
}
if (rx_ctx->ctx.state == TKIP_STATE_NOT_INIT ||
rx_ctx->iv32 != iv32) {
/* IV16 wrapped around - perform TKIP phase 1 */
tkip_mixing_phase1(tk, &rx_ctx->ctx, ta, iv32);
}
if (key->local->ops->update_tkip_key &&
key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE &&
rx_ctx->ctx.state != TKIP_STATE_PHASE1_HW_UPLOADED) {
struct ieee80211_sub_if_data *sdata = key->sdata;
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
sdata = container_of(key->sdata->bss,
struct ieee80211_sub_if_data, u.ap);
drv_update_tkip_key(key->local, sdata, &key->conf, key->sta,
iv32, rx_ctx->ctx.p1k);
rx_ctx->ctx.state = TKIP_STATE_PHASE1_HW_UPLOADED;
}
tkip_mixing_phase2(tk, &rx_ctx->ctx, iv16, rc4key);
res = ieee80211_wep_decrypt_data(ctx, rc4key, 16 , pos, payload_len - 12 );
done:
if (res == TKIP_DECRYPT_OK) {
/*
* Record previously received IV , will be copied into the
* key information after MIC verification . It is possible
* that we don ' t catch replays of fragments but that ' s ok
* because the Michael MIC verification will then fail .
*/
*out_iv32 = iv32;
*out_iv16 = iv16;
}
return res;
}
Messung V0.5 in Prozent C=97 H=93 G=94
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-09-27)
¤
*© Formatika GbR, Deutschland