]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/CyaSSL/ctaocrypt/src/arc4.c
Update CyaSSL to latest version.
[freertos] / FreeRTOS-Plus / Source / CyaSSL / ctaocrypt / src / arc4.c
1 /* arc4.c
2  *
3  * Copyright (C) 2006-2014 wolfSSL Inc.
4  *
5  * This file is part of CyaSSL.
6  *
7  * CyaSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * CyaSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #ifdef HAVE_CONFIG_H
23     #include <config.h>
24 #endif
25
26 #include <cyassl/ctaocrypt/settings.h>
27
28 #ifndef NO_RC4
29
30 #include <cyassl/ctaocrypt/arc4.h>
31
32
33 #ifdef HAVE_CAVIUM
34     static void Arc4CaviumSetKey(Arc4* arc4, const byte* key, word32 length);
35     static void Arc4CaviumProcess(Arc4* arc4, byte* out, const byte* in,
36                                   word32 length);
37 #endif
38
39
40 void Arc4SetKey(Arc4* arc4, const byte* key, word32 length)
41 {
42     word32 i;
43     word32 keyIndex = 0, stateIndex = 0;
44
45 #ifdef HAVE_CAVIUM
46     if (arc4->magic == CYASSL_ARC4_CAVIUM_MAGIC)
47         return Arc4CaviumSetKey(arc4, key, length);
48 #endif
49
50     arc4->x = 1;
51     arc4->y = 0;
52
53     for (i = 0; i < ARC4_STATE_SIZE; i++)
54         arc4->state[i] = (byte)i;
55
56     for (i = 0; i < ARC4_STATE_SIZE; i++) {
57         word32 a = arc4->state[i];
58         stateIndex += key[keyIndex] + a;
59         stateIndex &= 0xFF;
60         arc4->state[i] = arc4->state[stateIndex];
61         arc4->state[stateIndex] = (byte)a;
62
63         if (++keyIndex >= length)
64             keyIndex = 0;
65     }
66 }
67
68
69 static INLINE byte MakeByte(word32* x, word32* y, byte* s)
70 {
71     word32 a = s[*x], b;
72     *y = (*y+a) & 0xff;
73
74     b = s[*y];
75     s[*x] = (byte)b;
76     s[*y] = (byte)a;
77     *x = (*x+1) & 0xff;
78
79     return s[(a+b) & 0xff];
80 }
81
82
83 void Arc4Process(Arc4* arc4, byte* out, const byte* in, word32 length)
84 {
85     word32 x;
86     word32 y;
87
88 #ifdef HAVE_CAVIUM
89     if (arc4->magic == CYASSL_ARC4_CAVIUM_MAGIC)
90         return Arc4CaviumProcess(arc4, out, in, length);
91 #endif
92
93     x = arc4->x;
94     y = arc4->y;
95
96     while(length--)
97         *out++ = *in++ ^ MakeByte(&x, &y, arc4->state);
98
99     arc4->x = (byte)x;
100     arc4->y = (byte)y;
101 }
102
103
104 #ifdef HAVE_CAVIUM
105
106 #include <cyassl/ctaocrypt/logging.h>
107 #include "cavium_common.h"
108
109 /* Initiliaze Arc4 for use with Nitrox device */
110 int Arc4InitCavium(Arc4* arc4, int devId)
111 {
112     if (arc4 == NULL)
113         return -1;
114
115     if (CspAllocContext(CONTEXT_SSL, &arc4->contextHandle, devId) != 0)
116         return -1;
117
118     arc4->devId = devId;
119     arc4->magic = CYASSL_ARC4_CAVIUM_MAGIC;
120    
121     return 0;
122 }
123
124
125 /* Free Arc4 from use with Nitrox device */
126 void Arc4FreeCavium(Arc4* arc4)
127 {
128     if (arc4 == NULL)
129         return;
130
131     if (arc4->magic != CYASSL_ARC4_CAVIUM_MAGIC)
132         return;
133
134     CspFreeContext(CONTEXT_SSL, arc4->contextHandle, arc4->devId);
135     arc4->magic = 0;
136 }
137
138
139 static void Arc4CaviumSetKey(Arc4* arc4, const byte* key, word32 length)
140 {
141     word32 requestId;
142
143     if (CspInitializeRc4(CAVIUM_BLOCKING, arc4->contextHandle, length,
144                          (byte*)key, &requestId, arc4->devId) != 0) {
145         CYASSL_MSG("Bad Cavium Arc4 Init");
146     }
147 }
148
149
150 static void Arc4CaviumProcess(Arc4* arc4, byte* out, const byte* in,
151                               word32 length)
152 {
153     word   offset = 0;
154     word32 requestId;
155
156     while (length > CYASSL_MAX_16BIT) {
157         word16 slen = (word16)CYASSL_MAX_16BIT;
158         if (CspEncryptRc4(CAVIUM_BLOCKING, arc4->contextHandle,CAVIUM_UPDATE,
159                           slen, (byte*)in + offset, out + offset, &requestId,
160                           arc4->devId) != 0) {
161             CYASSL_MSG("Bad Cavium Arc4 Encrypt");
162         }
163         length -= CYASSL_MAX_16BIT;
164         offset += CYASSL_MAX_16BIT;
165     }
166     if (length) {
167         word16 slen = (word16)length;
168         if (CspEncryptRc4(CAVIUM_BLOCKING, arc4->contextHandle,CAVIUM_UPDATE,
169                           slen, (byte*)in + offset, out + offset, &requestId,
170                           arc4->devId) != 0) {
171             CYASSL_MSG("Bad Cavium Arc4 Encrypt");
172         }
173     }
174 }
175
176 #endif /* HAVE_CAVIUM */
177
178 #endif /* NO_ARC4 */
179