Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
xtea.c
00001 /* 00002 * An 32-bit implementation of the XTEA algorithm 00003 * 00004 * Copyright (C) 2006-2014, 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 #if !defined(POLARSSL_CONFIG_FILE) 00027 #include "polarssl/config.h" 00028 #else 00029 #include POLARSSL_CONFIG_FILE 00030 #endif 00031 00032 #if defined(POLARSSL_XTEA_C) 00033 00034 #include "polarssl/xtea.h" 00035 00036 #if defined(POLARSSL_PLATFORM_C) 00037 #include "polarssl/platform.h" 00038 #else 00039 #define polarssl_printf printf 00040 #endif 00041 00042 #if !defined(POLARSSL_XTEA_ALT) 00043 00044 /* 00045 * 32-bit integer manipulation macros (big endian) 00046 */ 00047 #ifndef GET_UINT32_BE 00048 #define GET_UINT32_BE(n,b,i) \ 00049 { \ 00050 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ 00051 | ( (uint32_t) (b)[(i) + 1] << 16 ) \ 00052 | ( (uint32_t) (b)[(i) + 2] << 8 ) \ 00053 | ( (uint32_t) (b)[(i) + 3] ); \ 00054 } 00055 #endif 00056 00057 #ifndef PUT_UINT32_BE 00058 #define PUT_UINT32_BE(n,b,i) \ 00059 { \ 00060 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ 00061 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ 00062 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ 00063 (b)[(i) + 3] = (unsigned char) ( (n) ); \ 00064 } 00065 #endif 00066 00067 /* 00068 * XTEA key schedule 00069 */ 00070 void xtea_setup( xtea_context *ctx, const unsigned char key[16] ) 00071 { 00072 int i; 00073 00074 memset(ctx, 0, sizeof(xtea_context)); 00075 00076 for( i = 0; i < 4; i++ ) 00077 { 00078 GET_UINT32_BE( ctx->k [i], key, i << 2 ); 00079 } 00080 } 00081 00082 /* 00083 * XTEA encrypt function 00084 */ 00085 int xtea_crypt_ecb( xtea_context *ctx, int mode, 00086 const unsigned char input[8], unsigned char output[8]) 00087 { 00088 uint32_t *k, v0, v1, i; 00089 00090 k = ctx->k ; 00091 00092 GET_UINT32_BE( v0, input, 0 ); 00093 GET_UINT32_BE( v1, input, 4 ); 00094 00095 if( mode == XTEA_ENCRYPT ) 00096 { 00097 uint32_t sum = 0, delta = 0x9E3779B9; 00098 00099 for( i = 0; i < 32; i++ ) 00100 { 00101 v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); 00102 sum += delta; 00103 v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]); 00104 } 00105 } 00106 else /* XTEA_DECRYPT */ 00107 { 00108 uint32_t delta = 0x9E3779B9, sum = delta * 32; 00109 00110 for( i = 0; i < 32; i++ ) 00111 { 00112 v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]); 00113 sum -= delta; 00114 v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); 00115 } 00116 } 00117 00118 PUT_UINT32_BE( v0, output, 0 ); 00119 PUT_UINT32_BE( v1, output, 4 ); 00120 00121 return( 0 ); 00122 } 00123 00124 #if defined(POLARSSL_CIPHER_MODE_CBC) 00125 /* 00126 * XTEA-CBC buffer encryption/decryption 00127 */ 00128 int xtea_crypt_cbc( xtea_context *ctx, int mode, size_t length, 00129 unsigned char iv[8], const unsigned char *input, 00130 unsigned char *output) 00131 { 00132 int i; 00133 unsigned char temp[8]; 00134 00135 if( length % 8 ) 00136 return( POLARSSL_ERR_XTEA_INVALID_INPUT_LENGTH ); 00137 00138 if( mode == XTEA_DECRYPT ) 00139 { 00140 while( length > 0 ) 00141 { 00142 memcpy( temp, input, 8 ); 00143 xtea_crypt_ecb( ctx, mode, input, output ); 00144 00145 for(i = 0; i < 8; i++) 00146 output[i] = (unsigned char)( output[i] ^ iv[i] ); 00147 00148 memcpy( iv, temp, 8 ); 00149 00150 input += 8; 00151 output += 8; 00152 length -= 8; 00153 } 00154 } 00155 else 00156 { 00157 while( length > 0 ) 00158 { 00159 for( i = 0; i < 8; i++ ) 00160 output[i] = (unsigned char)( input[i] ^ iv[i] ); 00161 00162 xtea_crypt_ecb( ctx, mode, output, output ); 00163 memcpy( iv, output, 8 ); 00164 00165 input += 8; 00166 output += 8; 00167 length -= 8; 00168 } 00169 } 00170 00171 return( 0 ); 00172 } 00173 #endif /* POLARSSL_CIPHER_MODE_CBC */ 00174 #endif /* !POLARSSL_XTEA_ALT */ 00175 00176 #if defined(POLARSSL_SELF_TEST) 00177 00178 #include <string.h> 00179 #include <stdio.h> 00180 00181 /* 00182 * XTEA tests vectors (non-official) 00183 */ 00184 00185 static const unsigned char xtea_test_key[6][16] = 00186 { 00187 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 00188 0x0c, 0x0d, 0x0e, 0x0f }, 00189 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 00190 0x0c, 0x0d, 0x0e, 0x0f }, 00191 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 00192 0x0c, 0x0d, 0x0e, 0x0f }, 00193 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00194 0x00, 0x00, 0x00, 0x00 }, 00195 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00196 0x00, 0x00, 0x00, 0x00 }, 00197 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00198 0x00, 0x00, 0x00, 0x00 } 00199 }; 00200 00201 static const unsigned char xtea_test_pt[6][8] = 00202 { 00203 { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 }, 00204 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, 00205 { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f }, 00206 { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 }, 00207 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, 00208 { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 } 00209 }; 00210 00211 static const unsigned char xtea_test_ct[6][8] = 00212 { 00213 { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 }, 00214 { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 }, 00215 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, 00216 { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 }, 00217 { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d }, 00218 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 } 00219 }; 00220 00221 /* 00222 * Checkup routine 00223 */ 00224 int xtea_self_test( int verbose ) 00225 { 00226 int i; 00227 unsigned char buf[8]; 00228 xtea_context ctx; 00229 00230 for( i = 0; i < 6; i++ ) 00231 { 00232 if( verbose != 0 ) 00233 polarssl_printf( " XTEA test #%d: ", i + 1 ); 00234 00235 memcpy( buf, xtea_test_pt[i], 8 ); 00236 00237 xtea_setup( &ctx, xtea_test_key[i] ); 00238 xtea_crypt_ecb( &ctx, XTEA_ENCRYPT, buf, buf ); 00239 00240 if( memcmp( buf, xtea_test_ct[i], 8 ) != 0 ) 00241 { 00242 if( verbose != 0 ) 00243 polarssl_printf( "failed\n" ); 00244 00245 return( 1 ); 00246 } 00247 00248 if( verbose != 0 ) 00249 polarssl_printf( "passed\n" ); 00250 } 00251 00252 if( verbose != 0 ) 00253 polarssl_printf( "\n" ); 00254 00255 return( 0 ); 00256 } 00257 00258 #endif /* POLARSSL_SELF_TEST */ 00259 00260 #endif /* POLARSSL_XTEA_C */ 00261 00262
Generated on Tue Jul 12 2022 19:40:21 by
1.7.2