/home/dko/projects/mobilec/trunk/src/security/xyssl-0.7/library/arc4.c

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

Generated on Fri May 16 14:49:55 2008 for Mobile-C by  doxygen 1.5.4