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