1/*
2 *   wep.c - WEP functions
3 *
4 * Copyright (C) 2015, Broadcom Corporation
5 * All Rights Reserved.
6 *
7 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
8 * the contents of this file may not be disclosed to third parties, copied
9 * or duplicated in any form, in whole or in part, without the prior
10 * written permission of Broadcom Corporation.
11 *
12 * $Id: wep.c 358033 2012-09-20 23:57:22Z $
13 */
14
15#include <bcm_cfg.h>
16#include <typedefs.h>
17
18/* include wl driver config file if this file is compiled for driver */
19#ifdef BCMDRIVER
20#include <osl.h>
21#else
22#include <string.h>
23#endif /* BCMDRIVER */
24
25#include <bcmutils.h>
26#include <bcmcrypto/rc4.h>
27#include <bcmcrypto/wep.h>
28#include <proto/802.11.h>
29
30/* WEP-encrypt a buffer */
31/* assumes a contiguous buffer, with IV prepended, and with enough space at
32 * the end for the ICV
33 */
34void
35BCMROMFN(wep_encrypt)(uint buf_len, uint8 *buf, uint sec_len, uint8 *sec_data)
36{
37	uint8 key_data[16];
38	uint32 ICV;
39	rc4_ks_t ks;
40	uint8 *body = buf + DOT11_IV_LEN;
41	uint body_len = buf_len - (DOT11_IV_LEN + DOT11_ICV_LEN);
42	uint8 *picv = body + body_len;
43
44	memcpy(key_data, buf, 3);
45	memcpy(&key_data[3], sec_data, sec_len);
46
47	prepare_key(key_data, sec_len + 3, &ks);
48
49	/* append ICV */
50	ICV = ~hndcrc32(body, body_len, CRC32_INIT_VALUE);
51	picv[0] = ICV & 0xff;
52	picv[1] = (ICV >> 8) & 0xff;
53	picv[2] = (ICV >> 16) & 0xff;
54	picv[3] = (ICV >> 24) & 0xff;
55
56	rc4(body, body_len + DOT11_ICV_LEN, &ks);
57}
58
59/* WEP-decrypt
60 * Assumes a contigous buffer, with IV prepended.
61 * Returns TRUE if ICV check passes, FALSE otherwise
62 *
63 */
64bool
65BCMROMFN(wep_decrypt)(uint buf_len, uint8 *buf, uint sec_len, uint8 *sec_data)
66{
67	uint8 key_data[16];
68	rc4_ks_t ks;
69
70	memcpy(key_data, buf, 3);
71	memcpy(&key_data[3], sec_data, sec_len);
72
73	prepare_key(key_data, sec_len + 3, &ks);
74
75	rc4(buf + DOT11_IV_LEN, buf_len - DOT11_IV_LEN, &ks);
76
77	return (hndcrc32(buf + DOT11_IV_LEN, buf_len - DOT11_IV_LEN, CRC32_INIT_VALUE) ==
78		CRC32_GOOD_VALUE);
79}
80