source: trunk/library/arc4.c @ 1014

Revision 1014, 3.9 KB checked in by paul, 13 months ago (diff)
  • Major type rewrite of int to size_t for most variables and arguments used for buffer lengths and loops
Line 
1/*
2 *  An implementation of the ARCFOUR algorithm
3 *
4 *  Copyright (C) 2006-2010, Brainspark B.V.
5 *
6 *  This file is part of PolarSSL (http://www.polarssl.org)
7 *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8 *
9 *  All rights reserved.
10 *
11 *  This program is free software; you can redistribute it and/or modify
12 *  it under the terms of the GNU General Public License as published by
13 *  the Free Software Foundation; either version 2 of the License, or
14 *  (at your option) any later version.
15 *
16 *  This program is distributed in the hope that it will be useful,
17 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 *  GNU General Public License for more details.
20 *
21 *  You should have received a copy of the GNU General Public License along
22 *  with this program; if not, write to the Free Software Foundation, Inc.,
23 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25/*
26 *  The ARCFOUR algorithm was publicly disclosed on 94/09.
27 *
28 *  http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0
29 */
30
31#include "polarssl/config.h"
32
33#if defined(POLARSSL_ARC4_C)
34
35#include "polarssl/arc4.h"
36
37/*
38 * ARC4 key schedule
39 */
40void arc4_setup( arc4_context *ctx, const unsigned char *key, unsigned int keylen )
41{
42    int i, j, a;
43    unsigned int k;
44    unsigned char *m;
45
46    ctx->x = 0;
47    ctx->y = 0;
48    m = ctx->m;
49
50    for( i = 0; i < 256; i++ )
51        m[i] = (unsigned char) i;
52
53    j = k = 0;
54
55    for( i = 0; i < 256; i++, k++ )
56    {
57        if( k >= keylen ) k = 0;
58
59        a = m[i];
60        j = ( j + a + key[k] ) & 0xFF;
61        m[i] = m[j];
62        m[j] = (unsigned char) a;
63    }
64}
65
66/*
67 * ARC4 cipher function
68 */
69int arc4_crypt( arc4_context *ctx, size_t length, const unsigned char *input,
70                unsigned char *output )
71{
72    int x, y, a, b;
73    size_t i;
74    unsigned char *m;
75
76    x = ctx->x;
77    y = ctx->y;
78    m = ctx->m;
79
80    for( i = 0; i < length; i++ )
81    {
82        x = ( x + 1 ) & 0xFF; a = m[x];
83        y = ( y + a ) & 0xFF; b = m[y];
84
85        m[x] = (unsigned char) b;
86        m[y] = (unsigned char) a;
87
88        output[i] = (unsigned char)
89            ( input[i] ^ m[(unsigned char)( a + b )] );
90    }
91
92    ctx->x = x;
93    ctx->y = y;
94
95    return( 0 );
96}
97
98#if defined(POLARSSL_SELF_TEST)
99
100#include <string.h>
101#include <stdio.h>
102
103/*
104 * ARC4 tests vectors as posted by Eric Rescorla in sep. 1994:
105 *
106 * http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0
107 */
108static const unsigned char arc4_test_key[3][8] =
109{
110    { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
111    { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
112    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
113};
114
115static const unsigned char arc4_test_pt[3][8] =
116{
117    { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
118    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
119    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
120};
121
122static const unsigned char arc4_test_ct[3][8] =
123{
124    { 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 },
125    { 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 },
126    { 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A }
127};
128
129/*
130 * Checkup routine
131 */
132int arc4_self_test( int verbose )
133{
134    int i;
135    unsigned char ibuf[8];
136    unsigned char obuf[8];
137    arc4_context ctx;
138
139    for( i = 0; i < 3; i++ )
140    {
141        if( verbose != 0 )
142            printf( "  ARC4 test #%d: ", i + 1 );
143
144        memcpy( ibuf, arc4_test_pt[i], 8 );
145
146        arc4_setup( &ctx, (unsigned char *) arc4_test_key[i], 8 );
147        arc4_crypt( &ctx, 8, ibuf, obuf );
148
149        if( memcmp( obuf, arc4_test_ct[i], 8 ) != 0 )
150        {
151            if( verbose != 0 )
152                printf( "failed\n" );
153
154            return( 1 );
155        }
156
157        if( verbose != 0 )
158            printf( "passed\n" );
159    }
160
161    if( verbose != 0 )
162        printf( "\n" );
163
164    return( 0 );
165}
166
167#endif
168
169#endif
Note: See TracBrowser for help on using the repository browser.

What are you looking for?