mbed TLS library
Dependents: HTTPClient-SSL WS_SERVER
xtea.c
00001 /* 00002 * An 32-bit implementation of the XTEA algorithm 00003 * 00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved 00005 * 00006 * This file is part of mbed TLS (https://tls.mbed.org) 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License along 00019 * with this program; if not, write to the Free Software Foundation, Inc., 00020 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00021 */ 00022 00023 #if !defined(POLARSSL_CONFIG_FILE) 00024 #include "polarssl/config.h" 00025 #else 00026 #include POLARSSL_CONFIG_FILE 00027 #endif 00028 00029 #if defined(POLARSSL_XTEA_C) 00030 00031 #include "polarssl/xtea.h" 00032 00033 #include <string.h> 00034 00035 #if defined(POLARSSL_SELF_TEST) 00036 #if defined(POLARSSL_PLATFORM_C) 00037 #include "polarssl/platform.h" 00038 #else 00039 #include <stdio.h> 00040 #define polarssl_printf printf 00041 #endif /* POLARSSL_PLATFORM_C */ 00042 #endif /* POLARSSL_SELF_TEST */ 00043 00044 #if !defined(POLARSSL_XTEA_ALT) 00045 00046 /* Implementation that should never be optimized out by the compiler */ 00047 static void polarssl_zeroize( void *v, size_t n ) { 00048 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 00049 } 00050 00051 /* 00052 * 32-bit integer manipulation macros (big endian) 00053 */ 00054 #ifndef GET_UINT32_BE 00055 #define GET_UINT32_BE(n,b,i) \ 00056 { \ 00057 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ 00058 | ( (uint32_t) (b)[(i) + 1] << 16 ) \ 00059 | ( (uint32_t) (b)[(i) + 2] << 8 ) \ 00060 | ( (uint32_t) (b)[(i) + 3] ); \ 00061 } 00062 #endif 00063 00064 #ifndef PUT_UINT32_BE 00065 #define PUT_UINT32_BE(n,b,i) \ 00066 { \ 00067 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ 00068 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ 00069 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ 00070 (b)[(i) + 3] = (unsigned char) ( (n) ); \ 00071 } 00072 #endif 00073 00074 void xtea_init( xtea_context *ctx ) 00075 { 00076 memset( ctx, 0, sizeof( xtea_context ) ); 00077 } 00078 00079 void xtea_free( xtea_context *ctx ) 00080 { 00081 if( ctx == NULL ) 00082 return; 00083 00084 polarssl_zeroize( ctx, sizeof( xtea_context ) ); 00085 } 00086 00087 /* 00088 * XTEA key schedule 00089 */ 00090 void xtea_setup( xtea_context *ctx, const unsigned char key[16] ) 00091 { 00092 int i; 00093 00094 memset( ctx, 0, sizeof(xtea_context) ); 00095 00096 for( i = 0; i < 4; i++ ) 00097 { 00098 GET_UINT32_BE( ctx->k [i], key, i << 2 ); 00099 } 00100 } 00101 00102 /* 00103 * XTEA encrypt function 00104 */ 00105 int xtea_crypt_ecb( xtea_context *ctx, int mode, 00106 const unsigned char input[8], unsigned char output[8]) 00107 { 00108 uint32_t *k, v0, v1, i; 00109 00110 k = ctx->k ; 00111 00112 GET_UINT32_BE( v0, input, 0 ); 00113 GET_UINT32_BE( v1, input, 4 ); 00114 00115 if( mode == XTEA_ENCRYPT ) 00116 { 00117 uint32_t sum = 0, delta = 0x9E3779B9; 00118 00119 for( i = 0; i < 32; i++ ) 00120 { 00121 v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); 00122 sum += delta; 00123 v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]); 00124 } 00125 } 00126 else /* XTEA_DECRYPT */ 00127 { 00128 uint32_t delta = 0x9E3779B9, sum = delta * 32; 00129 00130 for( i = 0; i < 32; i++ ) 00131 { 00132 v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]); 00133 sum -= delta; 00134 v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); 00135 } 00136 } 00137 00138 PUT_UINT32_BE( v0, output, 0 ); 00139 PUT_UINT32_BE( v1, output, 4 ); 00140 00141 return( 0 ); 00142 } 00143 00144 #if defined(POLARSSL_CIPHER_MODE_CBC) 00145 /* 00146 * XTEA-CBC buffer encryption/decryption 00147 */ 00148 int xtea_crypt_cbc( xtea_context *ctx, int mode, size_t length, 00149 unsigned char iv[8], const unsigned char *input, 00150 unsigned char *output) 00151 { 00152 int i; 00153 unsigned char temp[8]; 00154 00155 if( length % 8 ) 00156 return( POLARSSL_ERR_XTEA_INVALID_INPUT_LENGTH ); 00157 00158 if( mode == XTEA_DECRYPT ) 00159 { 00160 while( length > 0 ) 00161 { 00162 memcpy( temp, input, 8 ); 00163 xtea_crypt_ecb( ctx, mode, input, output ); 00164 00165 for( i = 0; i < 8; i++ ) 00166 output[i] = (unsigned char)( output[i] ^ iv[i] ); 00167 00168 memcpy( iv, temp, 8 ); 00169 00170 input += 8; 00171 output += 8; 00172 length -= 8; 00173 } 00174 } 00175 else 00176 { 00177 while( length > 0 ) 00178 { 00179 for( i = 0; i < 8; i++ ) 00180 output[i] = (unsigned char)( input[i] ^ iv[i] ); 00181 00182 xtea_crypt_ecb( ctx, mode, output, output ); 00183 memcpy( iv, output, 8 ); 00184 00185 input += 8; 00186 output += 8; 00187 length -= 8; 00188 } 00189 } 00190 00191 return( 0 ); 00192 } 00193 #endif /* POLARSSL_CIPHER_MODE_CBC */ 00194 #endif /* !POLARSSL_XTEA_ALT */ 00195 00196 #if defined(POLARSSL_SELF_TEST) 00197 00198 /* 00199 * XTEA tests vectors (non-official) 00200 */ 00201 00202 static const unsigned char xtea_test_key[6][16] = 00203 { 00204 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 00205 0x0c, 0x0d, 0x0e, 0x0f }, 00206 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 00207 0x0c, 0x0d, 0x0e, 0x0f }, 00208 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 00209 0x0c, 0x0d, 0x0e, 0x0f }, 00210 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00211 0x00, 0x00, 0x00, 0x00 }, 00212 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00213 0x00, 0x00, 0x00, 0x00 }, 00214 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00215 0x00, 0x00, 0x00, 0x00 } 00216 }; 00217 00218 static const unsigned char xtea_test_pt[6][8] = 00219 { 00220 { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 }, 00221 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, 00222 { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f }, 00223 { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 }, 00224 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, 00225 { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 } 00226 }; 00227 00228 static const unsigned char xtea_test_ct[6][8] = 00229 { 00230 { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 }, 00231 { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 }, 00232 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, 00233 { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 }, 00234 { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d }, 00235 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 } 00236 }; 00237 00238 /* 00239 * Checkup routine 00240 */ 00241 int xtea_self_test( int verbose ) 00242 { 00243 int i, ret = 0; 00244 unsigned char buf[8]; 00245 xtea_context ctx; 00246 00247 xtea_init( &ctx ); 00248 for( i = 0; i < 6; i++ ) 00249 { 00250 if( verbose != 0 ) 00251 polarssl_printf( " XTEA test #%d: ", i + 1 ); 00252 00253 memcpy( buf, xtea_test_pt[i], 8 ); 00254 00255 xtea_setup( &ctx, xtea_test_key[i] ); 00256 xtea_crypt_ecb( &ctx, XTEA_ENCRYPT, buf, buf ); 00257 00258 if( memcmp( buf, xtea_test_ct[i], 8 ) != 0 ) 00259 { 00260 if( verbose != 0 ) 00261 polarssl_printf( "failed\n" ); 00262 00263 ret = 1; 00264 goto exit; 00265 } 00266 00267 if( verbose != 0 ) 00268 polarssl_printf( "passed\n" ); 00269 } 00270 00271 if( verbose != 0 ) 00272 polarssl_printf( "\n" ); 00273 00274 exit: 00275 xtea_free( &ctx ); 00276 00277 return( ret ); 00278 } 00279 00280 #endif /* POLARSSL_SELF_TEST */ 00281 00282 #endif /* POLARSSL_XTEA_C */ 00283
Generated on Tue Jul 12 2022 13:50:39 by 1.7.2