PolarSSL v1.3.7
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 /*
45  * 32-bit integer manipulation macros (big endian)
46  */
47 #ifndef GET_UINT32_BE
48 #define GET_UINT32_BE(n,b,i) \
49 { \
50  (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
51  | ( (uint32_t) (b)[(i) + 1] << 16 ) \
52  | ( (uint32_t) (b)[(i) + 2] << 8 ) \
53  | ( (uint32_t) (b)[(i) + 3] ); \
54 }
55 #endif
56 
57 #ifndef PUT_UINT32_BE
58 #define PUT_UINT32_BE(n,b,i) \
59 { \
60  (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
61  (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
62  (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
63  (b)[(i) + 3] = (unsigned char) ( (n) ); \
64 }
65 #endif
66 
67 /*
68  * XTEA key schedule
69  */
70 void xtea_setup( xtea_context *ctx, const unsigned char key[16] )
71 {
72  int i;
73 
74  memset(ctx, 0, sizeof(xtea_context));
75 
76  for( i = 0; i < 4; i++ )
77  {
78  GET_UINT32_BE( ctx->k[i], key, i << 2 );
79  }
80 }
81 
82 /*
83  * XTEA encrypt function
84  */
85 int xtea_crypt_ecb( xtea_context *ctx, int mode,
86  const unsigned char input[8], unsigned char output[8])
87 {
88  uint32_t *k, v0, v1, i;
89 
90  k = ctx->k;
91 
92  GET_UINT32_BE( v0, input, 0 );
93  GET_UINT32_BE( v1, input, 4 );
94 
95  if( mode == XTEA_ENCRYPT )
96  {
97  uint32_t sum = 0, delta = 0x9E3779B9;
98 
99  for( i = 0; i < 32; i++ )
100  {
101  v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
102  sum += delta;
103  v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
104  }
105  }
106  else /* XTEA_DECRYPT */
107  {
108  uint32_t delta = 0x9E3779B9, sum = delta * 32;
109 
110  for( i = 0; i < 32; i++ )
111  {
112  v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
113  sum -= delta;
114  v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
115  }
116  }
117 
118  PUT_UINT32_BE( v0, output, 0 );
119  PUT_UINT32_BE( v1, output, 4 );
120 
121  return( 0 );
122 }
123 
124 #if defined(POLARSSL_CIPHER_MODE_CBC)
125 /*
126  * XTEA-CBC buffer encryption/decryption
127  */
128 int xtea_crypt_cbc( xtea_context *ctx, int mode, size_t length,
129  unsigned char iv[8], const unsigned char *input,
130  unsigned char *output)
131 {
132  int i;
133  unsigned char temp[8];
134 
135  if( length % 8 )
137 
138  if( mode == XTEA_DECRYPT )
139  {
140  while( length > 0 )
141  {
142  memcpy( temp, input, 8 );
143  xtea_crypt_ecb( ctx, mode, input, output );
144 
145  for(i = 0; i < 8; i++)
146  output[i] = (unsigned char)( output[i] ^ iv[i] );
147 
148  memcpy( iv, temp, 8 );
149 
150  input += 8;
151  output += 8;
152  length -= 8;
153  }
154  }
155  else
156  {
157  while( length > 0 )
158  {
159  for( i = 0; i < 8; i++ )
160  output[i] = (unsigned char)( input[i] ^ iv[i] );
161 
162  xtea_crypt_ecb( ctx, mode, output, output );
163  memcpy( iv, output, 8 );
164 
165  input += 8;
166  output += 8;
167  length -= 8;
168  }
169  }
170 
171  return( 0 );
172 }
173 #endif /* POLARSSL_CIPHER_MODE_CBC */
174 #endif /* !POLARSSL_XTEA_ALT */
175 
176 #if defined(POLARSSL_SELF_TEST)
177 
178 #include <string.h>
179 #include <stdio.h>
180 
181 /*
182  * XTEA tests vectors (non-official)
183  */
184 
185 static const unsigned char xtea_test_key[6][16] =
186 {
187  { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
188  0x0c, 0x0d, 0x0e, 0x0f },
189  { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
190  0x0c, 0x0d, 0x0e, 0x0f },
191  { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
192  0x0c, 0x0d, 0x0e, 0x0f },
193  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194  0x00, 0x00, 0x00, 0x00 },
195  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
196  0x00, 0x00, 0x00, 0x00 },
197  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
198  0x00, 0x00, 0x00, 0x00 }
199 };
200 
201 static const unsigned char xtea_test_pt[6][8] =
202 {
203  { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
204  { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
205  { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f },
206  { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
207  { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
208  { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 }
209 };
210 
211 static const unsigned char xtea_test_ct[6][8] =
212 {
213  { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 },
214  { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 },
215  { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
216  { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 },
217  { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d },
218  { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }
219 };
220 
221 /*
222  * Checkup routine
223  */
224 int xtea_self_test( int verbose )
225 {
226  int i;
227  unsigned char buf[8];
228  xtea_context ctx;
229 
230  for( i = 0; i < 6; i++ )
231  {
232  if( verbose != 0 )
233  polarssl_printf( " XTEA test #%d: ", i + 1 );
234 
235  memcpy( buf, xtea_test_pt[i], 8 );
236 
237  xtea_setup( &ctx, xtea_test_key[i] );
238  xtea_crypt_ecb( &ctx, XTEA_ENCRYPT, buf, buf );
239 
240  if( memcmp( buf, xtea_test_ct[i], 8 ) != 0 )
241  {
242  if( verbose != 0 )
243  polarssl_printf( "failed\n" );
244 
245  return( 1 );
246  }
247 
248  if( verbose != 0 )
249  polarssl_printf( "passed\n" );
250  }
251 
252  if( verbose != 0 )
253  polarssl_printf( "\n" );
254 
255  return( 0 );
256 }
257 
258 #endif /* POLARSSL_SELF_TEST */
259 
260 #endif /* POLARSSL_XTEA_C */
#define POLARSSL_ERR_XTEA_INVALID_INPUT_LENGTH
The data input has an invalid length.
Definition: xtea.h:48
Configuration options (set of defines)
PolarSSL Platform abstraction layer.
int xtea_crypt_ecb(xtea_context *ctx, int mode, const unsigned char input[8], unsigned char output[8])
XTEA cipher function.
void xtea_setup(xtea_context *ctx, const unsigned char key[16])
XTEA key schedule.
XTEA block cipher (32-bit)
#define XTEA_DECRYPT
Definition: xtea.h:46
#define XTEA_ENCRYPT
Definition: xtea.h:45
int xtea_crypt_cbc(xtea_context *ctx, int mode, size_t length, unsigned char iv[8], const unsigned char *input, unsigned char *output)
XTEA CBC cipher function.
#define polarssl_printf
Definition: platform.h:109
XTEA context structure.
Definition: xtea.h:61
int xtea_self_test(int verbose)
Checkup routine.
uint32_t k[4]
Definition: xtea.h:63