2 * An 32-bit implementation of the XTEA algorithm
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: Apache-2.0
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 * This file is part of mbed TLS (https://tls.mbed.org)
22 #if !defined(MBEDTLS_CONFIG_FILE)
23 #include "mbedtls/config.h"
25 #include MBEDTLS_CONFIG_FILE
28 #if defined(MBEDTLS_XTEA_C)
30 #include "mbedtls/xtea.h"
34 #if defined(MBEDTLS_SELF_TEST)
35 #if defined(MBEDTLS_PLATFORM_C)
36 #include "mbedtls/platform.h"
39 #define mbedtls_printf printf
40 #endif /* MBEDTLS_PLATFORM_C */
41 #endif /* MBEDTLS_SELF_TEST */
43 #if !defined(MBEDTLS_XTEA_ALT)
45 /* Implementation that should never be optimized out by the compiler */
46 static void mbedtls_zeroize( void *v
, size_t n
) {
47 volatile unsigned char *p
= v
; while( n
-- ) *p
++ = 0;
51 * 32-bit integer manipulation macros (big endian)
54 #define GET_UINT32_BE(n,b,i) \
56 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
57 | ( (uint32_t) (b)[(i) + 1] << 16 ) \
58 | ( (uint32_t) (b)[(i) + 2] << 8 ) \
59 | ( (uint32_t) (b)[(i) + 3] ); \
64 #define PUT_UINT32_BE(n,b,i) \
66 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
67 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
68 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
69 (b)[(i) + 3] = (unsigned char) ( (n) ); \
73 void mbedtls_xtea_init( mbedtls_xtea_context
*ctx
)
75 memset( ctx
, 0, sizeof( mbedtls_xtea_context
) );
78 void mbedtls_xtea_free( mbedtls_xtea_context
*ctx
)
83 mbedtls_zeroize( ctx
, sizeof( mbedtls_xtea_context
) );
89 void mbedtls_xtea_setup( mbedtls_xtea_context
*ctx
, const unsigned char key
[16] )
93 memset( ctx
, 0, sizeof(mbedtls_xtea_context
) );
95 for( i
= 0; i
< 4; i
++ )
97 GET_UINT32_BE( ctx
->k
[i
], key
, i
<< 2 );
102 * XTEA encrypt function
104 int mbedtls_xtea_crypt_ecb( mbedtls_xtea_context
*ctx
, int mode
,
105 const unsigned char input
[8], unsigned char output
[8])
107 uint32_t *k
, v0
, v1
, i
;
111 GET_UINT32_BE( v0
, input
, 0 );
112 GET_UINT32_BE( v1
, input
, 4 );
114 if( mode
== MBEDTLS_XTEA_ENCRYPT
)
116 uint32_t sum
= 0, delta
= 0x9E3779B9;
118 for( i
= 0; i
< 32; i
++ )
120 v0
+= (((v1
<< 4) ^ (v1
>> 5)) + v1
) ^ (sum
+ k
[sum
& 3]);
122 v1
+= (((v0
<< 4) ^ (v0
>> 5)) + v0
) ^ (sum
+ k
[(sum
>>11) & 3]);
125 else /* MBEDTLS_XTEA_DECRYPT */
127 uint32_t delta
= 0x9E3779B9, sum
= delta
* 32;
129 for( i
= 0; i
< 32; i
++ )
131 v1
-= (((v0
<< 4) ^ (v0
>> 5)) + v0
) ^ (sum
+ k
[(sum
>>11) & 3]);
133 v0
-= (((v1
<< 4) ^ (v1
>> 5)) + v1
) ^ (sum
+ k
[sum
& 3]);
137 PUT_UINT32_BE( v0
, output
, 0 );
138 PUT_UINT32_BE( v1
, output
, 4 );
143 #if defined(MBEDTLS_CIPHER_MODE_CBC)
145 * XTEA-CBC buffer encryption/decryption
147 int mbedtls_xtea_crypt_cbc( mbedtls_xtea_context
*ctx
, int mode
, size_t length
,
148 unsigned char iv
[8], const unsigned char *input
,
149 unsigned char *output
)
152 unsigned char temp
[8];
155 return( MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH
);
157 if( mode
== MBEDTLS_XTEA_DECRYPT
)
161 memcpy( temp
, input
, 8 );
162 mbedtls_xtea_crypt_ecb( ctx
, mode
, input
, output
);
164 for( i
= 0; i
< 8; i
++ )
165 output
[i
] = (unsigned char)( output
[i
] ^ iv
[i
] );
167 memcpy( iv
, temp
, 8 );
178 for( i
= 0; i
< 8; i
++ )
179 output
[i
] = (unsigned char)( input
[i
] ^ iv
[i
] );
181 mbedtls_xtea_crypt_ecb( ctx
, mode
, output
, output
);
182 memcpy( iv
, output
, 8 );
192 #endif /* MBEDTLS_CIPHER_MODE_CBC */
193 #endif /* !MBEDTLS_XTEA_ALT */
195 #if defined(MBEDTLS_SELF_TEST)
198 * XTEA tests vectors (non-official)
201 static const unsigned char xtea_test_key
[6][16] =
203 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
204 0x0c, 0x0d, 0x0e, 0x0f },
205 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
206 0x0c, 0x0d, 0x0e, 0x0f },
207 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
208 0x0c, 0x0d, 0x0e, 0x0f },
209 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210 0x00, 0x00, 0x00, 0x00 },
211 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
212 0x00, 0x00, 0x00, 0x00 },
213 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
214 0x00, 0x00, 0x00, 0x00 }
217 static const unsigned char xtea_test_pt
[6][8] =
219 { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
220 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
221 { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f },
222 { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
223 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
224 { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 }
227 static const unsigned char xtea_test_ct
[6][8] =
229 { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 },
230 { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 },
231 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
232 { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 },
233 { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d },
234 { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }
240 int mbedtls_xtea_self_test( int verbose
)
243 unsigned char buf
[8];
244 mbedtls_xtea_context ctx
;
246 mbedtls_xtea_init( &ctx
);
247 for( i
= 0; i
< 6; i
++ )
250 mbedtls_printf( " XTEA test #%d: ", i
+ 1 );
252 memcpy( buf
, xtea_test_pt
[i
], 8 );
254 mbedtls_xtea_setup( &ctx
, xtea_test_key
[i
] );
255 mbedtls_xtea_crypt_ecb( &ctx
, MBEDTLS_XTEA_ENCRYPT
, buf
, buf
);
257 if( memcmp( buf
, xtea_test_ct
[i
], 8 ) != 0 )
260 mbedtls_printf( "failed\n" );
267 mbedtls_printf( "passed\n" );
271 mbedtls_printf( "\n" );
274 mbedtls_xtea_free( &ctx
);
279 #endif /* MBEDTLS_SELF_TEST */
281 #endif /* MBEDTLS_XTEA_C */