diff --git a/ChangeLog b/ChangeLog index 0bbe5b0d7..59ce6db82 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,10 +1,9 @@ PolarSSL ChangeLog = Version 0.x released on 2009-01-?? -? * Migrated XySSL to PolarSSL -? * Added warning for use of old defines + * Migrated XySSL to PolarSSL + * Added XTEA symmetric cipher ? * Added Camellia symmetric cipher -? * Added XTEA symmetric cipher ? * Fixed dangerous bug that can cause a heap overflow in rsa_pkcs1_decrypt diff --git a/include/polarssl/config.h b/include/polarssl/config.h index 9fd0821f4..a85f8fdb2 100644 --- a/include/polarssl/config.h +++ b/include/polarssl/config.h @@ -299,4 +299,10 @@ */ #define POLARSSL_X509_WRITE_C +/* + * Module: library/xtea.c + * Caller: + */ +#define POLARSSL_XTEA_C + #endif /* config.h */ diff --git a/include/polarssl/xtea.h b/include/polarssl/xtea.h new file mode 100644 index 000000000..7a6b55814 --- /dev/null +++ b/include/polarssl/xtea.h @@ -0,0 +1,72 @@ +/** + * \file xtea.h + * + * Copyright (C) 2009 Paul Bakker + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef POLARSSL_XTEA_H +#define POLARSSL_XTEA_H + +#define XTEA_ENCRYPT 1 +#define XTEA_DECRYPT 0 + + +/** + * \brief XTEA context structure + */ +typedef struct +{ + unsigned long k[4]; /*!< key */ +} +xtea_context; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief XTEA key schedule + * + * \param ctx XTEA context to be initialized + * \param key the secret key + */ +void xtea_setup( xtea_context *ctx, unsigned char key[16] ); + +/** + * \brief XTEA cipher function + * + * \param ctx XTEA context + * \param mode XTEA_ENCRYPT or XTEA_DECRYPT + * \param input 8-byte input block + * \param output 8-byte output block + */ +void xtea_crypt( xtea_context *ctx, + int mode, + unsigned char input[8], + unsigned char output[8] ); + +/* + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int xtea_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* xtea.h */ diff --git a/library/Makefile b/library/Makefile index b28c858a0..611540f35 100644 --- a/library/Makefile +++ b/library/Makefile @@ -24,7 +24,7 @@ OBJS= aes.o arc4.o base64.o \ net.o padlock.o rsa.o \ sha1.o sha2.o sha4.o \ ssl_cli.o ssl_srv.o ssl_tls.o \ - timing.o x509parse.o + timing.o x509parse.o xtea.o .SILENT: diff --git a/library/xtea.c b/library/xtea.c new file mode 100644 index 000000000..c775c1ea1 --- /dev/null +++ b/library/xtea.c @@ -0,0 +1,184 @@ +/* + * An 32-bit implementation of the XTEA algorithm + * + * Copyright (C) 2009 Paul Bakker + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "polarssl/config.h" + +#if defined(POLARSSL_XTEA_C) + +#include "polarssl/xtea.h" + +#include + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_ULONG_BE +#define GET_ULONG_BE(n,b,i) \ +{ \ + (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ + | ( (unsigned long) (b)[(i) + 1] << 16 ) \ + | ( (unsigned long) (b)[(i) + 2] << 8 ) \ + | ( (unsigned long) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_ULONG_BE +#define PUT_ULONG_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +/* + * XTEA key schedule + */ +void xtea_setup( xtea_context *ctx, unsigned char key[16] ) +{ + int i; + + memset(ctx, 0, sizeof(xtea_context)); + + for( i = 0; i < 4; i++ ) + { + GET_ULONG_BE( ctx->k[i], key, i << 2 ); + } +} + +/* + * XTEA encrypt function + */ +void xtea_crypt_ecb( xtea_context *ctx, int mode, unsigned char input[8], unsigned char output[8]) +{ + unsigned long *k, v0, v1, i; + + k = ctx->k; + + GET_ULONG_BE( v0, input, 0 ); + GET_ULONG_BE( v1, input, 4 ); + + if( mode == XTEA_ENCRYPT ) + { + unsigned long sum = 0, delta = 0x9E3779B9; + + for( i = 0; i < 32; i++ ) + { + v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); + sum += delta; + v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]); + } + } + else /* XTEA_DECRYPT */ + { + unsigned long delta = 0x9E3779B9, sum = delta * 32; + + for( i = 0; i < 32; i++ ) + { + v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]); + sum -= delta; + v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); + } + } + + PUT_ULONG_BE( v0, output, 0 ); + PUT_ULONG_BE( v1, output, 4 ); +} + +#if defined(POLARSSL_SELF_TEST) + +#include +#include + +/* + * XTEA tests vectors (non-official) + */ + +static const unsigned char xtea_test_key[6][16] = +{ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}; + +static const unsigned char xtea_test_pt[6][8] = +{ + { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, + { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f }, + { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, + { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 } +}; + +static const unsigned char xtea_test_ct[6][8] = +{ + { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 }, + { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, + { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 }, + { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 } +}; + +/* + * Checkup routine + */ +int xtea_self_test( int verbose ) +{ + int i; + unsigned char buf[8]; + xtea_context ctx; + + for( i = 0; i < 6; i++ ) + { + if( verbose != 0 ) + printf( " XTEA test #%d: ", i + 1 ); + + memcpy( buf, xtea_test_pt[i], 8 ); + + xtea_setup( &ctx, (unsigned char *) xtea_test_key[i] ); + xtea_crypt_ecb( &ctx, XTEA_ENCRYPT, buf, buf ); + + if( memcmp( buf, xtea_test_ct[i], 8 ) != 0 ) + { + if( verbose != 0 ) + printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + printf( "passed\n" ); + } + + if( verbose != 0 ) + printf( "\n" ); + + return( 0 ); +} + +#endif + +#endif diff --git a/programs/test/selftest.c b/programs/test/selftest.c index 602857314..9607c0727 100644 --- a/programs/test/selftest.c +++ b/programs/test/selftest.c @@ -42,6 +42,7 @@ #include "polarssl/bignum.h" #include "polarssl/rsa.h" #include "polarssl/x509.h" +#include "polarssl/xtea.h" int main( int argc, char *argv[] ) { @@ -120,6 +121,11 @@ int main( int argc, char *argv[] ) return( ret ); #endif +#if defined(POLARSSL_XTEA_C) + if( ( ret = xtea_self_test( v ) ) != 0 ) + return( ret ); +#endif + if( v != 0 ) { printf( " [ All tests passed ]\n\n" );