]>
Commit | Line | Data |
---|---|---|
700d8687 OM |
1 | /* |
2 | * An implementation of the ARCFOUR algorithm | |
3 | * | |
4 | * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved | |
5 | * SPDX-License-Identifier: GPL-2.0 | |
6 | * | |
7 | * This program 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 | * This program 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 along | |
18 | * with this program; if not, write to the Free Software Foundation, Inc., | |
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
20 | * | |
21 | * This file is part of mbed TLS (https://tls.mbed.org) | |
22 | */ | |
23 | /* | |
24 | * The ARCFOUR algorithm was publicly disclosed on 94/09. | |
25 | * | |
26 | * http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0 | |
27 | */ | |
28 | ||
29 | #if !defined(MBEDTLS_CONFIG_FILE) | |
30 | #include "mbedtls/config.h" | |
31 | #else | |
32 | #include MBEDTLS_CONFIG_FILE | |
33 | #endif | |
34 | ||
35 | #if defined(MBEDTLS_ARC4_C) | |
36 | ||
37 | #include "mbedtls/arc4.h" | |
38 | #include "mbedtls/platform_util.h" | |
39 | ||
40 | #include <string.h> | |
41 | ||
42 | #if defined(MBEDTLS_SELF_TEST) | |
43 | #if defined(MBEDTLS_PLATFORM_C) | |
44 | #include "mbedtls/platform.h" | |
45 | #else | |
46 | #include <stdio.h> | |
47 | #define mbedtls_printf printf | |
48 | #endif /* MBEDTLS_PLATFORM_C */ | |
49 | #endif /* MBEDTLS_SELF_TEST */ | |
50 | ||
51 | #if !defined(MBEDTLS_ARC4_ALT) | |
52 | ||
53 | void mbedtls_arc4_init( mbedtls_arc4_context *ctx ) | |
54 | { | |
55 | memset( ctx, 0, sizeof( mbedtls_arc4_context ) ); | |
56 | } | |
57 | ||
58 | void mbedtls_arc4_free( mbedtls_arc4_context *ctx ) | |
59 | { | |
60 | if( ctx == NULL ) | |
61 | return; | |
62 | ||
63 | mbedtls_platform_zeroize( ctx, sizeof( mbedtls_arc4_context ) ); | |
64 | } | |
65 | ||
66 | /* | |
67 | * ARC4 key schedule | |
68 | */ | |
69 | void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key, | |
70 | unsigned int keylen ) | |
71 | { | |
72 | int i, j, a; | |
73 | unsigned int k; | |
74 | unsigned char *m; | |
75 | ||
76 | ctx->x = 0; | |
77 | ctx->y = 0; | |
78 | m = ctx->m; | |
79 | ||
80 | for( i = 0; i < 256; i++ ) | |
81 | m[i] = (unsigned char) i; | |
82 | ||
83 | j = k = 0; | |
84 | ||
85 | for( i = 0; i < 256; i++, k++ ) | |
86 | { | |
87 | if( k >= keylen ) k = 0; | |
88 | ||
89 | a = m[i]; | |
90 | j = ( j + a + key[k] ) & 0xFF; | |
91 | m[i] = m[j]; | |
92 | m[j] = (unsigned char) a; | |
93 | } | |
94 | } | |
95 | ||
96 | /* | |
97 | * ARC4 cipher function | |
98 | */ | |
99 | int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input, | |
100 | unsigned char *output ) | |
101 | { | |
102 | int x, y, a, b; | |
103 | size_t i; | |
104 | unsigned char *m; | |
105 | ||
106 | x = ctx->x; | |
107 | y = ctx->y; | |
108 | m = ctx->m; | |
109 | ||
110 | for( i = 0; i < length; i++ ) | |
111 | { | |
112 | x = ( x + 1 ) & 0xFF; a = m[x]; | |
113 | y = ( y + a ) & 0xFF; b = m[y]; | |
114 | ||
115 | m[x] = (unsigned char) b; | |
116 | m[y] = (unsigned char) a; | |
117 | ||
118 | output[i] = (unsigned char) | |
119 | ( input[i] ^ m[(unsigned char)( a + b )] ); | |
120 | } | |
121 | ||
122 | ctx->x = x; | |
123 | ctx->y = y; | |
124 | ||
125 | return( 0 ); | |
126 | } | |
127 | ||
128 | #endif /* !MBEDTLS_ARC4_ALT */ | |
129 | ||
130 | #if defined(MBEDTLS_SELF_TEST) | |
131 | /* | |
132 | * ARC4 tests vectors as posted by Eric Rescorla in sep. 1994: | |
133 | * | |
134 | * http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0 | |
135 | */ | |
136 | static const unsigned char arc4_test_key[3][8] = | |
137 | { | |
138 | { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, | |
139 | { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, | |
140 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } | |
141 | }; | |
142 | ||
143 | static const unsigned char arc4_test_pt[3][8] = | |
144 | { | |
145 | { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, | |
146 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, | |
147 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } | |
148 | }; | |
149 | ||
150 | static const unsigned char arc4_test_ct[3][8] = | |
151 | { | |
152 | { 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 }, | |
153 | { 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 }, | |
154 | { 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A } | |
155 | }; | |
156 | ||
157 | /* | |
158 | * Checkup routine | |
159 | */ | |
160 | int mbedtls_arc4_self_test( int verbose ) | |
161 | { | |
162 | int i, ret = 0; | |
163 | unsigned char ibuf[8]; | |
164 | unsigned char obuf[8]; | |
165 | mbedtls_arc4_context ctx; | |
166 | ||
167 | mbedtls_arc4_init( &ctx ); | |
168 | ||
169 | for( i = 0; i < 3; i++ ) | |
170 | { | |
171 | if( verbose != 0 ) | |
172 | mbedtls_printf( " ARC4 test #%d: ", i + 1 ); | |
173 | ||
174 | memcpy( ibuf, arc4_test_pt[i], 8 ); | |
175 | ||
176 | mbedtls_arc4_setup( &ctx, arc4_test_key[i], 8 ); | |
177 | mbedtls_arc4_crypt( &ctx, 8, ibuf, obuf ); | |
178 | ||
179 | if( memcmp( obuf, arc4_test_ct[i], 8 ) != 0 ) | |
180 | { | |
181 | if( verbose != 0 ) | |
182 | mbedtls_printf( "failed\n" ); | |
183 | ||
184 | ret = 1; | |
185 | goto exit; | |
186 | } | |
187 | ||
188 | if( verbose != 0 ) | |
189 | mbedtls_printf( "passed\n" ); | |
190 | } | |
191 | ||
192 | if( verbose != 0 ) | |
193 | mbedtls_printf( "\n" ); | |
194 | ||
195 | exit: | |
196 | mbedtls_arc4_free( &ctx ); | |
197 | ||
198 | return( ret ); | |
199 | } | |
200 | ||
201 | #endif /* MBEDTLS_SELF_TEST */ | |
202 | ||
203 | #endif /* MBEDTLS_ARC4_C */ |