xref: /reactos/dll/3rdparty/mbedtls/arc4.c (revision cbda039f)
1 /*
2  *  An implementation of the ARCFOUR algorithm
3  *
4  *  Copyright The Mbed TLS Contributors
5  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6  *
7  *  This file is provided under the Apache License 2.0, or the
8  *  GNU General Public License v2.0 or later.
9  *
10  *  **********
11  *  Apache License 2.0:
12  *
13  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
14  *  not use this file except in compliance with the License.
15  *  You may obtain a copy of the License at
16  *
17  *  http://www.apache.org/licenses/LICENSE-2.0
18  *
19  *  Unless required by applicable law or agreed to in writing, software
20  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22  *  See the License for the specific language governing permissions and
23  *  limitations under the License.
24  *
25  *  **********
26  *
27  *  **********
28  *  GNU General Public License v2.0 or later:
29  *
30  *  This program is free software; you can redistribute it and/or modify
31  *  it under the terms of the GNU General Public License as published by
32  *  the Free Software Foundation; either version 2 of the License, or
33  *  (at your option) any later version.
34  *
35  *  This program is distributed in the hope that it will be useful,
36  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
37  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
38  *  GNU General Public License for more details.
39  *
40  *  You should have received a copy of the GNU General Public License along
41  *  with this program; if not, write to the Free Software Foundation, Inc.,
42  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43  *
44  *  **********
45  */
46 /*
47  *  The ARCFOUR algorithm was publicly disclosed on 94/09.
48  *
49  *  http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0
50  */
51 
52 #if !defined(MBEDTLS_CONFIG_FILE)
53 #include "mbedtls/config.h"
54 #else
55 #include MBEDTLS_CONFIG_FILE
56 #endif
57 
58 #if defined(MBEDTLS_ARC4_C)
59 
60 #include "mbedtls/arc4.h"
61 #include "mbedtls/platform_util.h"
62 
63 #include <string.h>
64 
65 #if defined(MBEDTLS_SELF_TEST)
66 #if defined(MBEDTLS_PLATFORM_C)
67 #include "mbedtls/platform.h"
68 #else
69 #include <stdio.h>
70 #define mbedtls_printf printf
71 #endif /* MBEDTLS_PLATFORM_C */
72 #endif /* MBEDTLS_SELF_TEST */
73 
74 #if !defined(MBEDTLS_ARC4_ALT)
75 
mbedtls_arc4_init(mbedtls_arc4_context * ctx)76 void mbedtls_arc4_init( mbedtls_arc4_context *ctx )
77 {
78     memset( ctx, 0, sizeof( mbedtls_arc4_context ) );
79 }
80 
mbedtls_arc4_free(mbedtls_arc4_context * ctx)81 void mbedtls_arc4_free( mbedtls_arc4_context *ctx )
82 {
83     if( ctx == NULL )
84         return;
85 
86     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_arc4_context ) );
87 }
88 
89 /*
90  * ARC4 key schedule
91  */
mbedtls_arc4_setup(mbedtls_arc4_context * ctx,const unsigned char * key,unsigned int keylen)92 void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key,
93                  unsigned int keylen )
94 {
95     int i, j, a;
96     unsigned int k;
97     unsigned char *m;
98 
99     ctx->x = 0;
100     ctx->y = 0;
101     m = ctx->m;
102 
103     for( i = 0; i < 256; i++ )
104         m[i] = (unsigned char) i;
105 
106     j = k = 0;
107 
108     for( i = 0; i < 256; i++, k++ )
109     {
110         if( k >= keylen ) k = 0;
111 
112         a = m[i];
113         j = ( j + a + key[k] ) & 0xFF;
114         m[i] = m[j];
115         m[j] = (unsigned char) a;
116     }
117 }
118 
119 /*
120  * ARC4 cipher function
121  */
mbedtls_arc4_crypt(mbedtls_arc4_context * ctx,size_t length,const unsigned char * input,unsigned char * output)122 int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input,
123                 unsigned char *output )
124 {
125     int x, y, a, b;
126     size_t i;
127     unsigned char *m;
128 
129     x = ctx->x;
130     y = ctx->y;
131     m = ctx->m;
132 
133     for( i = 0; i < length; i++ )
134     {
135         x = ( x + 1 ) & 0xFF; a = m[x];
136         y = ( y + a ) & 0xFF; b = m[y];
137 
138         m[x] = (unsigned char) b;
139         m[y] = (unsigned char) a;
140 
141         output[i] = (unsigned char)
142             ( input[i] ^ m[(unsigned char)( a + b )] );
143     }
144 
145     ctx->x = x;
146     ctx->y = y;
147 
148     return( 0 );
149 }
150 
151 #endif /* !MBEDTLS_ARC4_ALT */
152 
153 #if defined(MBEDTLS_SELF_TEST)
154 /*
155  * ARC4 tests vectors as posted by Eric Rescorla in sep. 1994:
156  *
157  * http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0
158  */
159 static const unsigned char arc4_test_key[3][8] =
160 {
161     { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
162     { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
163     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
164 };
165 
166 static const unsigned char arc4_test_pt[3][8] =
167 {
168     { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
169     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
170     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
171 };
172 
173 static const unsigned char arc4_test_ct[3][8] =
174 {
175     { 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 },
176     { 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 },
177     { 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A }
178 };
179 
180 /*
181  * Checkup routine
182  */
mbedtls_arc4_self_test(int verbose)183 int mbedtls_arc4_self_test( int verbose )
184 {
185     int i, ret = 0;
186     unsigned char ibuf[8];
187     unsigned char obuf[8];
188     mbedtls_arc4_context ctx;
189 
190     mbedtls_arc4_init( &ctx );
191 
192     for( i = 0; i < 3; i++ )
193     {
194         if( verbose != 0 )
195             mbedtls_printf( "  ARC4 test #%d: ", i + 1 );
196 
197         memcpy( ibuf, arc4_test_pt[i], 8 );
198 
199         mbedtls_arc4_setup( &ctx, arc4_test_key[i], 8 );
200         mbedtls_arc4_crypt( &ctx, 8, ibuf, obuf );
201 
202         if( memcmp( obuf, arc4_test_ct[i], 8 ) != 0 )
203         {
204             if( verbose != 0 )
205                 mbedtls_printf( "failed\n" );
206 
207             ret = 1;
208             goto exit;
209         }
210 
211         if( verbose != 0 )
212             mbedtls_printf( "passed\n" );
213     }
214 
215     if( verbose != 0 )
216         mbedtls_printf( "\n" );
217 
218 exit:
219     mbedtls_arc4_free( &ctx );
220 
221     return( ret );
222 }
223 
224 #endif /* MBEDTLS_SELF_TEST */
225 
226 #endif /* MBEDTLS_ARC4_C */
227