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-2015, ARM Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 * 00019 * This file is part of mbed TLS (https://tls.mbed.org) 00020 */ 00021 00022 #if !defined(MBEDTLS_CONFIG_FILE) 00023 #include "mbedtls/config.h" 00024 #else 00025 #include MBEDTLS_CONFIG_FILE 00026 #endif 00027 00028 #if defined(MBEDTLS_XTEA_C) 00029 00030 #include "mbedtls/xtea.h" 00031 #include "mbedtls/platform_util.h" 00032 00033 #include <string.h> 00034 00035 #if defined(MBEDTLS_SELF_TEST) 00036 #if defined(MBEDTLS_PLATFORM_C) 00037 #include "mbedtls/platform.h" 00038 #else 00039 #include <stdio.h> 00040 #define mbedtls_printf printf 00041 #endif /* MBEDTLS_PLATFORM_C */ 00042 #endif /* MBEDTLS_SELF_TEST */ 00043 00044 #if !defined(MBEDTLS_XTEA_ALT) 00045 00046 /* 00047 * 32-bit integer manipulation macros (big endian) 00048 */ 00049 #ifndef GET_UINT32_BE 00050 #define GET_UINT32_BE(n,b,i) \ 00051 { \ 00052 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ 00053 | ( (uint32_t) (b)[(i) + 1] << 16 ) \ 00054 | ( (uint32_t) (b)[(i) + 2] << 8 ) \ 00055 | ( (uint32_t) (b)[(i) + 3] ); \ 00056 } 00057 #endif 00058 00059 #ifndef PUT_UINT32_BE 00060 #define PUT_UINT32_BE(n,b,i) \ 00061 { \ 00062 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ 00063 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ 00064 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ 00065 (b)[(i) + 3] = (unsigned char) ( (n) ); \ 00066 } 00067 #endif 00068 00069 void mbedtls_xtea_init( mbedtls_xtea_context *ctx ) 00070 { 00071 memset( ctx, 0, sizeof( mbedtls_xtea_context ) ); 00072 } 00073 00074 void mbedtls_xtea_free( mbedtls_xtea_context *ctx ) 00075 { 00076 if( ctx == NULL ) 00077 return; 00078 00079 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_xtea_context ) ); 00080 } 00081 00082 /* 00083 * XTEA key schedule 00084 */ 00085 void mbedtls_xtea_setup( mbedtls_xtea_context *ctx, const unsigned char key[16] ) 00086 { 00087 int i; 00088 00089 memset( ctx, 0, sizeof(mbedtls_xtea_context) ); 00090 00091 for( i = 0; i < 4; i++ ) 00092 { 00093 GET_UINT32_BE( ctx->k [i], key, i << 2 ); 00094 } 00095 } 00096 00097 /* 00098 * XTEA encrypt function 00099 */ 00100 int mbedtls_xtea_crypt_ecb( mbedtls_xtea_context *ctx, int mode, 00101 const unsigned char input[8], unsigned char output[8]) 00102 { 00103 uint32_t *k, v0, v1, i; 00104 00105 k = ctx->k ; 00106 00107 GET_UINT32_BE( v0, input, 0 ); 00108 GET_UINT32_BE( v1, input, 4 ); 00109 00110 if( mode == MBEDTLS_XTEA_ENCRYPT ) 00111 { 00112 uint32_t sum = 0, delta = 0x9E3779B9; 00113 00114 for( i = 0; i < 32; i++ ) 00115 { 00116 v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); 00117 sum += delta; 00118 v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]); 00119 } 00120 } 00121 else /* MBEDTLS_XTEA_DECRYPT */ 00122 { 00123 uint32_t delta = 0x9E3779B9, sum = delta * 32; 00124 00125 for( i = 0; i < 32; i++ ) 00126 { 00127 v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]); 00128 sum -= delta; 00129 v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); 00130 } 00131 } 00132 00133 PUT_UINT32_BE( v0, output, 0 ); 00134 PUT_UINT32_BE( v1, output, 4 ); 00135 00136 return( 0 ); 00137 } 00138 00139 #if defined(MBEDTLS_CIPHER_MODE_CBC) 00140 /* 00141 * XTEA-CBC buffer encryption/decryption 00142 */ 00143 int mbedtls_xtea_crypt_cbc( mbedtls_xtea_context *ctx, int mode, size_t length, 00144 unsigned char iv[8], const unsigned char *input, 00145 unsigned char *output) 00146 { 00147 int i; 00148 unsigned char temp[8]; 00149 00150 if( length % 8 ) 00151 return( MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH ); 00152 00153 if( mode == MBEDTLS_XTEA_DECRYPT ) 00154 { 00155 while( length > 0 ) 00156 { 00157 memcpy( temp, input, 8 ); 00158 mbedtls_xtea_crypt_ecb( ctx, mode, input, output ); 00159 00160 for( i = 0; i < 8; i++ ) 00161 output[i] = (unsigned char)( output[i] ^ iv[i] ); 00162 00163 memcpy( iv, temp, 8 ); 00164 00165 input += 8; 00166 output += 8; 00167 length -= 8; 00168 } 00169 } 00170 else 00171 { 00172 while( length > 0 ) 00173 { 00174 for( i = 0; i < 8; i++ ) 00175 output[i] = (unsigned char)( input[i] ^ iv[i] ); 00176 00177 mbedtls_xtea_crypt_ecb( ctx, mode, output, output ); 00178 memcpy( iv, output, 8 ); 00179 00180 input += 8; 00181 output += 8; 00182 length -= 8; 00183 } 00184 } 00185 00186 return( 0 ); 00187 } 00188 #endif /* MBEDTLS_CIPHER_MODE_CBC */ 00189 #endif /* !MBEDTLS_XTEA_ALT */ 00190 00191 #if defined(MBEDTLS_SELF_TEST) 00192 00193 /* 00194 * XTEA tests vectors (non-official) 00195 */ 00196 00197 static const unsigned char xtea_test_key[6][16] = 00198 { 00199 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 00200 0x0c, 0x0d, 0x0e, 0x0f }, 00201 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 00202 0x0c, 0x0d, 0x0e, 0x0f }, 00203 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 00204 0x0c, 0x0d, 0x0e, 0x0f }, 00205 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00206 0x00, 0x00, 0x00, 0x00 }, 00207 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00208 0x00, 0x00, 0x00, 0x00 }, 00209 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 00210 0x00, 0x00, 0x00, 0x00 } 00211 }; 00212 00213 static const unsigned char xtea_test_pt[6][8] = 00214 { 00215 { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 }, 00216 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, 00217 { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f }, 00218 { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 }, 00219 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, 00220 { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 } 00221 }; 00222 00223 static const unsigned char xtea_test_ct[6][8] = 00224 { 00225 { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 }, 00226 { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 }, 00227 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, 00228 { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 }, 00229 { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d }, 00230 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 } 00231 }; 00232 00233 /* 00234 * Checkup routine 00235 */ 00236 int mbedtls_xtea_self_test( int verbose ) 00237 { 00238 int i, ret = 0; 00239 unsigned char buf[8]; 00240 mbedtls_xtea_context ctx; 00241 00242 mbedtls_xtea_init( &ctx ); 00243 for( i = 0; i < 6; i++ ) 00244 { 00245 if( verbose != 0 ) 00246 mbedtls_printf( " XTEA test #%d: ", i + 1 ); 00247 00248 memcpy( buf, xtea_test_pt[i], 8 ); 00249 00250 mbedtls_xtea_setup( &ctx, xtea_test_key[i] ); 00251 mbedtls_xtea_crypt_ecb( &ctx, MBEDTLS_XTEA_ENCRYPT, buf, buf ); 00252 00253 if( memcmp( buf, xtea_test_ct[i], 8 ) != 0 ) 00254 { 00255 if( verbose != 0 ) 00256 mbedtls_printf( "failed\n" ); 00257 00258 ret = 1; 00259 goto exit; 00260 } 00261 00262 if( verbose != 0 ) 00263 mbedtls_printf( "passed\n" ); 00264 } 00265 00266 if( verbose != 0 ) 00267 mbedtls_printf( "\n" ); 00268 00269 exit: 00270 mbedtls_xtea_free( &ctx ); 00271 00272 return( ret ); 00273 } 00274 00275 #endif /* MBEDTLS_SELF_TEST */ 00276 00277 #endif /* MBEDTLS_XTEA_C */
Generated on Tue Jul 12 2022 12:46:20 by
