mbed TLS library

Dependents:   HTTPClient-SSL WS_SERVER

Committer:
ansond
Date:
Thu Jun 11 03:27:03 2015 +0000
Revision:
0:137634ff4186
initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ansond 0:137634ff4186 1 /*
ansond 0:137634ff4186 2 * An implementation of the ARCFOUR algorithm
ansond 0:137634ff4186 3 *
ansond 0:137634ff4186 4 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
ansond 0:137634ff4186 5 *
ansond 0:137634ff4186 6 * This file is part of mbed TLS (https://tls.mbed.org)
ansond 0:137634ff4186 7 *
ansond 0:137634ff4186 8 * This program is free software; you can redistribute it and/or modify
ansond 0:137634ff4186 9 * it under the terms of the GNU General Public License as published by
ansond 0:137634ff4186 10 * the Free Software Foundation; either version 2 of the License, or
ansond 0:137634ff4186 11 * (at your option) any later version.
ansond 0:137634ff4186 12 *
ansond 0:137634ff4186 13 * This program is distributed in the hope that it will be useful,
ansond 0:137634ff4186 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ansond 0:137634ff4186 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ansond 0:137634ff4186 16 * GNU General Public License for more details.
ansond 0:137634ff4186 17 *
ansond 0:137634ff4186 18 * You should have received a copy of the GNU General Public License along
ansond 0:137634ff4186 19 * with this program; if not, write to the Free Software Foundation, Inc.,
ansond 0:137634ff4186 20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
ansond 0:137634ff4186 21 */
ansond 0:137634ff4186 22 /*
ansond 0:137634ff4186 23 * The ARCFOUR algorithm was publicly disclosed on 94/09.
ansond 0:137634ff4186 24 *
ansond 0:137634ff4186 25 * http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0
ansond 0:137634ff4186 26 */
ansond 0:137634ff4186 27
ansond 0:137634ff4186 28 #if !defined(POLARSSL_CONFIG_FILE)
ansond 0:137634ff4186 29 #include "polarssl/config.h"
ansond 0:137634ff4186 30 #else
ansond 0:137634ff4186 31 #include POLARSSL_CONFIG_FILE
ansond 0:137634ff4186 32 #endif
ansond 0:137634ff4186 33
ansond 0:137634ff4186 34 #if defined(POLARSSL_ARC4_C)
ansond 0:137634ff4186 35
ansond 0:137634ff4186 36 #include "polarssl/arc4.h"
ansond 0:137634ff4186 37
ansond 0:137634ff4186 38 #include <string.h>
ansond 0:137634ff4186 39
ansond 0:137634ff4186 40 #if defined(POLARSSL_SELF_TEST)
ansond 0:137634ff4186 41 #if defined(POLARSSL_PLATFORM_C)
ansond 0:137634ff4186 42 #include "polarssl/platform.h"
ansond 0:137634ff4186 43 #else
ansond 0:137634ff4186 44 #include <stdio.h>
ansond 0:137634ff4186 45 #define polarssl_printf printf
ansond 0:137634ff4186 46 #endif /* POLARSSL_PLATFORM_C */
ansond 0:137634ff4186 47 #endif /* POLARSSL_SELF_TEST */
ansond 0:137634ff4186 48
ansond 0:137634ff4186 49 #if !defined(POLARSSL_ARC4_ALT)
ansond 0:137634ff4186 50
ansond 0:137634ff4186 51 /* Implementation that should never be optimized out by the compiler */
ansond 0:137634ff4186 52 static void polarssl_zeroize( void *v, size_t n ) {
ansond 0:137634ff4186 53 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
ansond 0:137634ff4186 54 }
ansond 0:137634ff4186 55
ansond 0:137634ff4186 56 void arc4_init( arc4_context *ctx )
ansond 0:137634ff4186 57 {
ansond 0:137634ff4186 58 memset( ctx, 0, sizeof( arc4_context ) );
ansond 0:137634ff4186 59 }
ansond 0:137634ff4186 60
ansond 0:137634ff4186 61 void arc4_free( arc4_context *ctx )
ansond 0:137634ff4186 62 {
ansond 0:137634ff4186 63 if( ctx == NULL )
ansond 0:137634ff4186 64 return;
ansond 0:137634ff4186 65
ansond 0:137634ff4186 66 polarssl_zeroize( ctx, sizeof( arc4_context ) );
ansond 0:137634ff4186 67 }
ansond 0:137634ff4186 68
ansond 0:137634ff4186 69 /*
ansond 0:137634ff4186 70 * ARC4 key schedule
ansond 0:137634ff4186 71 */
ansond 0:137634ff4186 72 void arc4_setup( arc4_context *ctx, const unsigned char *key,
ansond 0:137634ff4186 73 unsigned int keylen )
ansond 0:137634ff4186 74 {
ansond 0:137634ff4186 75 int i, j, a;
ansond 0:137634ff4186 76 unsigned int k;
ansond 0:137634ff4186 77 unsigned char *m;
ansond 0:137634ff4186 78
ansond 0:137634ff4186 79 ctx->x = 0;
ansond 0:137634ff4186 80 ctx->y = 0;
ansond 0:137634ff4186 81 m = ctx->m;
ansond 0:137634ff4186 82
ansond 0:137634ff4186 83 for( i = 0; i < 256; i++ )
ansond 0:137634ff4186 84 m[i] = (unsigned char) i;
ansond 0:137634ff4186 85
ansond 0:137634ff4186 86 j = k = 0;
ansond 0:137634ff4186 87
ansond 0:137634ff4186 88 for( i = 0; i < 256; i++, k++ )
ansond 0:137634ff4186 89 {
ansond 0:137634ff4186 90 if( k >= keylen ) k = 0;
ansond 0:137634ff4186 91
ansond 0:137634ff4186 92 a = m[i];
ansond 0:137634ff4186 93 j = ( j + a + key[k] ) & 0xFF;
ansond 0:137634ff4186 94 m[i] = m[j];
ansond 0:137634ff4186 95 m[j] = (unsigned char) a;
ansond 0:137634ff4186 96 }
ansond 0:137634ff4186 97 }
ansond 0:137634ff4186 98
ansond 0:137634ff4186 99 /*
ansond 0:137634ff4186 100 * ARC4 cipher function
ansond 0:137634ff4186 101 */
ansond 0:137634ff4186 102 int arc4_crypt( arc4_context *ctx, size_t length, const unsigned char *input,
ansond 0:137634ff4186 103 unsigned char *output )
ansond 0:137634ff4186 104 {
ansond 0:137634ff4186 105 int x, y, a, b;
ansond 0:137634ff4186 106 size_t i;
ansond 0:137634ff4186 107 unsigned char *m;
ansond 0:137634ff4186 108
ansond 0:137634ff4186 109 x = ctx->x;
ansond 0:137634ff4186 110 y = ctx->y;
ansond 0:137634ff4186 111 m = ctx->m;
ansond 0:137634ff4186 112
ansond 0:137634ff4186 113 for( i = 0; i < length; i++ )
ansond 0:137634ff4186 114 {
ansond 0:137634ff4186 115 x = ( x + 1 ) & 0xFF; a = m[x];
ansond 0:137634ff4186 116 y = ( y + a ) & 0xFF; b = m[y];
ansond 0:137634ff4186 117
ansond 0:137634ff4186 118 m[x] = (unsigned char) b;
ansond 0:137634ff4186 119 m[y] = (unsigned char) a;
ansond 0:137634ff4186 120
ansond 0:137634ff4186 121 output[i] = (unsigned char)
ansond 0:137634ff4186 122 ( input[i] ^ m[(unsigned char)( a + b )] );
ansond 0:137634ff4186 123 }
ansond 0:137634ff4186 124
ansond 0:137634ff4186 125 ctx->x = x;
ansond 0:137634ff4186 126 ctx->y = y;
ansond 0:137634ff4186 127
ansond 0:137634ff4186 128 return( 0 );
ansond 0:137634ff4186 129 }
ansond 0:137634ff4186 130
ansond 0:137634ff4186 131 #endif /* !POLARSSL_ARC4_ALT */
ansond 0:137634ff4186 132
ansond 0:137634ff4186 133 #if defined(POLARSSL_SELF_TEST)
ansond 0:137634ff4186 134 /*
ansond 0:137634ff4186 135 * ARC4 tests vectors as posted by Eric Rescorla in sep. 1994:
ansond 0:137634ff4186 136 *
ansond 0:137634ff4186 137 * http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0
ansond 0:137634ff4186 138 */
ansond 0:137634ff4186 139 static const unsigned char arc4_test_key[3][8] =
ansond 0:137634ff4186 140 {
ansond 0:137634ff4186 141 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
ansond 0:137634ff4186 142 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
ansond 0:137634ff4186 143 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
ansond 0:137634ff4186 144 };
ansond 0:137634ff4186 145
ansond 0:137634ff4186 146 static const unsigned char arc4_test_pt[3][8] =
ansond 0:137634ff4186 147 {
ansond 0:137634ff4186 148 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
ansond 0:137634ff4186 149 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
ansond 0:137634ff4186 150 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
ansond 0:137634ff4186 151 };
ansond 0:137634ff4186 152
ansond 0:137634ff4186 153 static const unsigned char arc4_test_ct[3][8] =
ansond 0:137634ff4186 154 {
ansond 0:137634ff4186 155 { 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 },
ansond 0:137634ff4186 156 { 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 },
ansond 0:137634ff4186 157 { 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A }
ansond 0:137634ff4186 158 };
ansond 0:137634ff4186 159
ansond 0:137634ff4186 160 /*
ansond 0:137634ff4186 161 * Checkup routine
ansond 0:137634ff4186 162 */
ansond 0:137634ff4186 163 int arc4_self_test( int verbose )
ansond 0:137634ff4186 164 {
ansond 0:137634ff4186 165 int i, ret = 0;
ansond 0:137634ff4186 166 unsigned char ibuf[8];
ansond 0:137634ff4186 167 unsigned char obuf[8];
ansond 0:137634ff4186 168 arc4_context ctx;
ansond 0:137634ff4186 169
ansond 0:137634ff4186 170 arc4_init( &ctx );
ansond 0:137634ff4186 171
ansond 0:137634ff4186 172 for( i = 0; i < 3; i++ )
ansond 0:137634ff4186 173 {
ansond 0:137634ff4186 174 if( verbose != 0 )
ansond 0:137634ff4186 175 polarssl_printf( " ARC4 test #%d: ", i + 1 );
ansond 0:137634ff4186 176
ansond 0:137634ff4186 177 memcpy( ibuf, arc4_test_pt[i], 8 );
ansond 0:137634ff4186 178
ansond 0:137634ff4186 179 arc4_setup( &ctx, arc4_test_key[i], 8 );
ansond 0:137634ff4186 180 arc4_crypt( &ctx, 8, ibuf, obuf );
ansond 0:137634ff4186 181
ansond 0:137634ff4186 182 if( memcmp( obuf, arc4_test_ct[i], 8 ) != 0 )
ansond 0:137634ff4186 183 {
ansond 0:137634ff4186 184 if( verbose != 0 )
ansond 0:137634ff4186 185 polarssl_printf( "failed\n" );
ansond 0:137634ff4186 186
ansond 0:137634ff4186 187 ret = 1;
ansond 0:137634ff4186 188 goto exit;
ansond 0:137634ff4186 189 }
ansond 0:137634ff4186 190
ansond 0:137634ff4186 191 if( verbose != 0 )
ansond 0:137634ff4186 192 polarssl_printf( "passed\n" );
ansond 0:137634ff4186 193 }
ansond 0:137634ff4186 194
ansond 0:137634ff4186 195 if( verbose != 0 )
ansond 0:137634ff4186 196 polarssl_printf( "\n" );
ansond 0:137634ff4186 197
ansond 0:137634ff4186 198 exit:
ansond 0:137634ff4186 199 arc4_free( &ctx );
ansond 0:137634ff4186 200
ansond 0:137634ff4186 201 return( ret );
ansond 0:137634ff4186 202 }
ansond 0:137634ff4186 203
ansond 0:137634ff4186 204 #endif /* POLARSSL_SELF_TEST */
ansond 0:137634ff4186 205
ansond 0:137634ff4186 206 #endif /* POLARSSL_ARC4_C */
ansond 0:137634ff4186 207