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