xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/mvl88w8977/mlan/esa/common/rc4.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /** @file rc4.c
2  *
3  *  @brief This file defines rc4 encrypt algorithm
4  *
5  * Copyright (C) 2014-2017, Marvell International Ltd.
6  *
7  * This software file (the "File") is distributed by Marvell International
8  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
9  * (the "License").  You may use, redistribute and/or modify this File in
10  * accordance with the terms and conditions of the License, a copy of which
11  * is available by writing to the Free Software Foundation, Inc.,
12  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
13  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
14  *
15  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
17  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
18  * this warranty disclaimer.
19  */
20 
21 /******************************************************
22 Change log:
23     03/07/2014: Initial version
24 ******************************************************/
25 #include "wltypes.h"
26 #include "rc4_rom.h"
27 #include "hostsa_ext_def.h"
28 #include "authenticator.h"
29 
30 typedef struct rc4_key {
31 	unsigned char state[256];
32 	unsigned char x;
33 	unsigned char y;
34 } rc4_key;
35 
36 static rc4_key rc4key;
37 
38 static void swap_byte(unsigned char *a, unsigned char *b);
39 
40 void
prepare_key(unsigned char * key_data_ptr,int key_data_len,rc4_key * key)41 prepare_key(unsigned char *key_data_ptr, int key_data_len, rc4_key *key)
42 {
43 	unsigned char index1;
44 	unsigned char index2;
45 	unsigned char *state;
46 	short counter;
47 
48 	state = &key->state[0];
49 	for (counter = 0; counter < 256; counter++) {
50 		state[counter] = counter;
51 	}
52 	key->x = 0;
53 	key->y = 0;
54 	index1 = 0;
55 	index2 = 0;
56 	for (counter = 0; counter < 256; counter++) {
57 		index2 = (key_data_ptr[index1] + state[counter] + index2) % 256;
58 		swap_byte(&state[counter], &state[index2]);
59 
60 		index1 = (index1 + 1) % key_data_len;
61 	}
62 }
63 
64 void
rc4(unsigned char * buffer_ptr,int buffer_len,int skip,rc4_key * key)65 rc4(unsigned char *buffer_ptr, int buffer_len, int skip, rc4_key *key)
66 {
67 	unsigned char x;
68 	unsigned char y;
69 	unsigned char *state;
70 	unsigned char xorIndex;
71 	short counter;
72 
73 	x = key->x;
74 	y = key->y;
75 
76 	state = &key->state[0];
77 
78 	for (counter = 0; counter < skip; counter++) {
79 		x = (x + 1) % 256;
80 		y = (state[x] + y) % 256;
81 		swap_byte(&state[x], &state[y]);
82 	}
83 
84 	for (counter = 0; counter < buffer_len; counter++) {
85 		x = (x + 1) % 256;
86 		y = (state[x] + y) % 256;
87 		swap_byte(&state[x], &state[y]);
88 
89 		xorIndex = (state[x] + state[y]) % 256;
90 
91 		buffer_ptr[counter] ^= state[xorIndex];
92 	}
93 	key->x = x;
94 	key->y = y;
95 }
96 
97 static void
swap_byte(unsigned char * a,unsigned char * b)98 swap_byte(unsigned char *a, unsigned char *b)
99 {
100 	unsigned char swapByte;
101 
102 	swapByte = *a;
103 	*a = *b;
104 	*b = swapByte;
105 }
106 
107 void
RC4_Encrypt(void * priv,unsigned char * Encr_Key,unsigned char * IV,unsigned short iv_length,unsigned char * Data,unsigned short data_length,unsigned short skipBytes)108 RC4_Encrypt(void *priv, unsigned char *Encr_Key,
109 	    unsigned char *IV,
110 	    unsigned short iv_length,
111 	    unsigned char *Data,
112 	    unsigned short data_length, unsigned short skipBytes)
113 {
114 	phostsa_private psapriv = (phostsa_private)priv;
115 	hostsa_util_fns *util_fns = &psapriv->util_fns;
116 	unsigned char key[32];
117 
118 	if (iv_length + 16 > sizeof(key)) {
119 		return;
120 	}
121 
122 	memcpy(util_fns, key, IV, iv_length);
123 	memcpy(util_fns, key + iv_length, Encr_Key, 16);
124 
125 	prepare_key(key, iv_length + 16, &rc4key);
126 	rc4(Data, data_length, skipBytes, &rc4key);
127 }
128