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