mbed TLS library

Dependents:   HTTPClient-SSL WS_SERVER

Committer:
ansond
Date:
Thu Jun 11 03:27:03 2015 +0000
Revision:
0:137634ff4186
initial commit

Who changed what in which revision?

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