PolarSSL v1.3.9
xtea.c
Go to the documentation of this file.
1 /*
2  * An 32-bit implementation of the XTEA algorithm
3  *
4  * Copyright (C) 2006-2014, Brainspark B.V.
5  *
6  * This file is part of PolarSSL (http://www.polarssl.org)
7  * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8  *
9  * All rights reserved.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25 
26 #if !defined(POLARSSL_CONFIG_FILE)
27 #include "polarssl/config.h"
28 #else
29 #include POLARSSL_CONFIG_FILE
30 #endif
31 
32 #if defined(POLARSSL_XTEA_C)
33 
34 #include "polarssl/xtea.h"
35 
36 #if defined(POLARSSL_PLATFORM_C)
37 #include "polarssl/platform.h"
38 #else
39 #define polarssl_printf printf
40 #endif
41 
42 #if !defined(POLARSSL_XTEA_ALT)
43 
44 /* Implementation that should never be optimized out by the compiler */
45 static void polarssl_zeroize( void *v, size_t n ) {
46  volatile unsigned char *p = v; while( n-- ) *p++ = 0;
47 }
48 
49 /*
50  * 32-bit integer manipulation macros (big endian)
51  */
52 #ifndef GET_UINT32_BE
53 #define GET_UINT32_BE(n,b,i) \
54 { \
55  (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
56  | ( (uint32_t) (b)[(i) + 1] << 16 ) \
57  | ( (uint32_t) (b)[(i) + 2] << 8 ) \
58  | ( (uint32_t) (b)[(i) + 3] ); \
59 }
60 #endif
61 
62 #ifndef PUT_UINT32_BE
63 #define PUT_UINT32_BE(n,b,i) \
64 { \
65  (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
66  (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
67  (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
68  (b)[(i) + 3] = (unsigned char) ( (n) ); \
69 }
70 #endif
71 
72 void xtea_init( xtea_context *ctx )
73 {
74  memset( ctx, 0, sizeof( xtea_context ) );
75 }
76 
77 void xtea_free( xtea_context *ctx )
78 {
79  if( ctx == NULL )
80  return;
81 
82  polarssl_zeroize( ctx, sizeof( xtea_context ) );
83 }
84 
85 /*
86  * XTEA key schedule
87  */
88 void xtea_setup( xtea_context *ctx, const unsigned char key[16] )
89 {
90  int i;
91 
92  memset( ctx, 0, sizeof(xtea_context) );
93 
94  for( i = 0; i < 4; i++ )
95  {
96  GET_UINT32_BE( ctx->k[i], key, i << 2 );
97  }
98 }
99 
100 /*
101  * XTEA encrypt function
102  */
103 int xtea_crypt_ecb( xtea_context *ctx, int mode,
104  const unsigned char input[8], unsigned char output[8])
105 {
106  uint32_t *k, v0, v1, i;
107 
108  k = ctx->k;
109 
110  GET_UINT32_BE( v0, input, 0 );
111  GET_UINT32_BE( v1, input, 4 );
112 
113  if( mode == XTEA_ENCRYPT )
114  {
115  uint32_t sum = 0, delta = 0x9E3779B9;
116 
117  for( i = 0; i < 32; i++ )
118  {
119  v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
120  sum += delta;
121  v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
122  }
123  }
124  else /* XTEA_DECRYPT */
125  {
126  uint32_t delta = 0x9E3779B9, sum = delta * 32;
127 
128  for( i = 0; i < 32; i++ )
129  {
130  v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
131  sum -= delta;
132  v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
133  }
134  }
135 
136  PUT_UINT32_BE( v0, output, 0 );
137  PUT_UINT32_BE( v1, output, 4 );
138 
139  return( 0 );
140 }
141 
142 #if defined(POLARSSL_CIPHER_MODE_CBC)
143 /*
144  * XTEA-CBC buffer encryption/decryption
145  */
146 int xtea_crypt_cbc( xtea_context *ctx, int mode, size_t length,
147  unsigned char iv[8], const unsigned char *input,
148  unsigned char *output)
149 {
150  int i;
151  unsigned char temp[8];
152 
153  if( length % 8 )
155 
156  if( mode == XTEA_DECRYPT )
157  {
158  while( length > 0 )
159  {
160  memcpy( temp, input, 8 );
161  xtea_crypt_ecb( ctx, mode, input, output );
162 
163  for( i = 0; i < 8; i++ )
164  output[i] = (unsigned char)( output[i] ^ iv[i] );
165 
166  memcpy( iv, temp, 8 );
167 
168  input += 8;
169  output += 8;
170  length -= 8;
171  }
172  }
173  else
174  {
175  while( length > 0 )
176  {
177  for( i = 0; i < 8; i++ )
178  output[i] = (unsigned char)( input[i] ^ iv[i] );
179 
180  xtea_crypt_ecb( ctx, mode, output, output );
181  memcpy( iv, output, 8 );
182 
183  input += 8;
184  output += 8;
185  length -= 8;
186  }
187  }
188 
189  return( 0 );
190 }
191 #endif /* POLARSSL_CIPHER_MODE_CBC */
192 #endif /* !POLARSSL_XTEA_ALT */
193 
194 #if defined(POLARSSL_SELF_TEST)
195 
196 #include <string.h>
197 #include <stdio.h>
198 
199 /*
200  * XTEA tests vectors (non-official)
201  */
202 
203 static const unsigned char xtea_test_key[6][16] =
204 {
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, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
210  0x0c, 0x0d, 0x0e, 0x0f },
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 },
215  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
216  0x00, 0x00, 0x00, 0x00 }
217 };
218 
219 static const unsigned char xtea_test_pt[6][8] =
220 {
221  { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
222  { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
223  { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f },
224  { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
225  { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
226  { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 }
227 };
228 
229 static const unsigned char xtea_test_ct[6][8] =
230 {
231  { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 },
232  { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 },
233  { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
234  { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 },
235  { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d },
236  { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }
237 };
238 
239 /*
240  * Checkup routine
241  */
242 int xtea_self_test( int verbose )
243 {
244  int i, ret = 0;
245  unsigned char buf[8];
246  xtea_context ctx;
247 
248  xtea_init( &ctx );
249  for( i = 0; i < 6; i++ )
250  {
251  if( verbose != 0 )
252  polarssl_printf( " XTEA test #%d: ", i + 1 );
253 
254  memcpy( buf, xtea_test_pt[i], 8 );
255 
256  xtea_setup( &ctx, xtea_test_key[i] );
257  xtea_crypt_ecb( &ctx, XTEA_ENCRYPT, buf, buf );
258 
259  if( memcmp( buf, xtea_test_ct[i], 8 ) != 0 )
260  {
261  if( verbose != 0 )
262  polarssl_printf( "failed\n" );
263 
264  ret = 1;
265  goto exit;
266  }
267 
268  if( verbose != 0 )
269  polarssl_printf( "passed\n" );
270  }
271 
272  if( verbose != 0 )
273  polarssl_printf( "\n" );
274 
275 exit:
276  xtea_free( &ctx );
277 
278  return( ret );
279 }
280 
281 #endif /* POLARSSL_SELF_TEST */
282 
283 #endif /* POLARSSL_XTEA_C */