- Main Page
- Data Structures
- Files

# arc4.c

Go to the documentation of this file.

    00001 /*
    00002  *  An implementation of the ARCFOUR algorithm
    00003  *
    00004  *  Copyright (C) 2006-2009, Paul Bakker <polarssl_maintainer at polarssl.org>
    00005  *  All rights reserved.
    00006  *
    00007  *  Joined copyright on original XySSL code with: Christophe Devine
    00008  *
    00009  *  This program is free software; you can redistribute it and/or modify
    00010  *  it under the terms of the GNU General Public License as published by
    00011  *  the Free Software Foundation; either version 2 of the License, or
    00012  *  (at your option) any later version.
    00013  *
    00014  *  This program is distributed in the hope that it will be useful,
    00015  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00017  *  GNU General Public License for more details.
    00018  *
    00019  *  You should have received a copy of the GNU General Public License along
    00020  *  with this program; if not, write to the Free Software Foundation, Inc.,
    00021  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    00022  */
    00023 /*
    00024  *  The ARCFOUR algorithm was publicly disclosed on 94/09.
    00025  *
    00026  *  http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0
    00027  */
    00028
    00029 #include "polarssl/config.h"
    00030
    00031 #if defined(POLARSSL_ARC4_C)
    00032
    00033 #include "polarssl/arc4.h"
    00034
    00035 /*
    00036  * ARC4 key schedule
    00037  */
    00038 void arc4_setup( arc4_context *ctx, unsigned char *key, int keylen )
    00039 {
    00040     int i, j, k, a;
    00041     unsigned char *m;
    00042
    00043     ctx->x = 0;
    00044     ctx->y = 0;
    00045     m = ctx->m;
    00046
    00047     for( i = 0; i < 256; i++ )
    00048         m[i] = (unsigned char) i;
    00049
    00050     j = k = 0;
    00051
    00052     for( i = 0; i < 256; i++, k++ )
    00053     {
    00054         if( k >= keylen ) k = 0;
    00055
    00056         a = m[i];
    00057         j = ( j + a + key[k] ) & 0xFF;
    00058         m[i] = m[j];
    00059         m[j] = (unsigned char) a;
    00060     }
    00061 }
    00062
    00063 /*
    00064  * ARC4 cipher function
    00065  */
    00066 void arc4_crypt( arc4_context *ctx, unsigned char *buf, int buflen )
    00067 {
    00068     int i, x, y, a, b;
    00069     unsigned char *m;
    00070
    00071     x = ctx->x;
    00072     y = ctx->y;
    00073     m = ctx->m;
    00074
    00075     for( i = 0; i < buflen; i++ )
    00076     {
    00077         x = ( x + 1 ) & 0xFF; a = m[x];
    00078         y = ( y + a ) & 0xFF; b = m[y];
    00079
    00080         m[x] = (unsigned char) b;
    00081         m[y] = (unsigned char) a;
    00082
    00083         buf[i] = (unsigned char)
    00084             ( buf[i] ^ m[(unsigned char)( a + b )] );
    00085     }
    00086
    00087     ctx->x = x;
    00088     ctx->y = y;
    00089 }
    00090
    00091 #if defined(POLARSSL_SELF_TEST)
    00092
    00093 #include <string.h>
    00094 #include <stdio.h>
    00095
    00096 /*
    00097  * ARC4 tests vectors as posted by Eric Rescorla in sep. 1994:
    00098  *
    00099  * http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0
    00100  */
    00101 static const unsigned char arc4_test_key[3][8] =
    00102 {
    00103     { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
    00104     { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
    00105     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
    00106 };
    00107
    00108 static const unsigned char arc4_test_pt[3][8] =
    00109 {
    00110     { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
    00111     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
    00112     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
    00113 };
    00114
    00115 static const unsigned char arc4_test_ct[3][8] =
    00116 {
    00117     { 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 },
    00118     { 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 },
    00119     { 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A }
    00120 };
    00121
    00122 /*
    00123  * Checkup routine
    00124  */
    00125 int arc4_self_test( int verbose )
    00126 {
    00127     int i;
    00128     unsigned char buf[8];
    00129     arc4_context ctx;
    00130
    00131     for( i = 0; i < 3; i++ )
    00132     {
    00133         if( verbose != 0 )
    00134             printf( "  ARC4 test #%d: ", i + 1 );
    00135
    00136         memcpy( buf, arc4_test_pt[i], 8 );
    00137
    00138         arc4_setup( &ctx, (unsigned char *) arc4_test_key[i], 8 );
    00139         arc4_crypt( &ctx, buf, 8 );
    00140
    00141         if( memcmp( buf, arc4_test_ct[i], 8 ) != 0 )
    00142         {
    00143             if( verbose != 0 )
    00144                 printf( "failed\n" );
    00145
    00146             return( 1 );
    00147         }
    00148
    00149         if( verbose != 0 )
    00150             printf( "passed\n" );
    00151     }
    00152
    00153     if( verbose != 0 )
    00154         printf( "\n" );
    00155
    00156     return( 0 );
    00157 }
    00158
    00159 #endif
    00160
    00161 #endif