Example program to test AES-GCM functionality. Used for a workshop

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers xtea.c Source File

xtea.c

00001 /*
00002  *  An 32-bit implementation of the XTEA algorithm
00003  *
00004  *  Copyright (C) 2006-2014, Brainspark B.V.
00005  *
00006  *  This file is part of PolarSSL (http://www.polarssl.org)
00007  *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
00008  *
00009  *  All rights reserved.
00010  *
00011  *  This program is free software; you can redistribute it and/or modify
00012  *  it under the terms of the GNU General Public License as published by
00013  *  the Free Software Foundation; either version 2 of the License, or
00014  *  (at your option) any later version.
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU General Public License for more details.
00020  *
00021  *  You should have received a copy of the GNU General Public License along
00022  *  with this program; if not, write to the Free Software Foundation, Inc.,
00023  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00024  */
00025 
00026 #if !defined(POLARSSL_CONFIG_FILE)
00027 #include "polarssl/config.h"
00028 #else
00029 #include POLARSSL_CONFIG_FILE
00030 #endif
00031 
00032 #if defined(POLARSSL_XTEA_C)
00033 
00034 #include "polarssl/xtea.h"
00035 
00036 #if defined(POLARSSL_PLATFORM_C)
00037 #include "polarssl/platform.h"
00038 #else
00039 #define polarssl_printf printf
00040 #endif
00041 
00042 #if !defined(POLARSSL_XTEA_ALT)
00043 
00044 /*
00045  * 32-bit integer manipulation macros (big endian)
00046  */
00047 #ifndef GET_UINT32_BE
00048 #define GET_UINT32_BE(n,b,i)                            \
00049 {                                                       \
00050     (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
00051         | ( (uint32_t) (b)[(i) + 1] << 16 )             \
00052         | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
00053         | ( (uint32_t) (b)[(i) + 3]       );            \
00054 }
00055 #endif
00056 
00057 #ifndef PUT_UINT32_BE
00058 #define PUT_UINT32_BE(n,b,i)                            \
00059 {                                                       \
00060     (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
00061     (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
00062     (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
00063     (b)[(i) + 3] = (unsigned char) ( (n)       );       \
00064 }
00065 #endif
00066 
00067 /*
00068  * XTEA key schedule
00069  */
00070 void xtea_setup( xtea_context *ctx, const unsigned char key[16] )
00071 {
00072     int i;
00073 
00074     memset(ctx, 0, sizeof(xtea_context));
00075 
00076     for( i = 0; i < 4; i++ )
00077     {
00078         GET_UINT32_BE( ctx->k [i], key, i << 2 );
00079     }
00080 }
00081 
00082 /*
00083  * XTEA encrypt function
00084  */
00085 int xtea_crypt_ecb( xtea_context *ctx, int mode,
00086                     const unsigned char input[8], unsigned char output[8])
00087 {
00088     uint32_t *k, v0, v1, i;
00089 
00090     k = ctx->k ;
00091 
00092     GET_UINT32_BE( v0, input, 0 );
00093     GET_UINT32_BE( v1, input, 4 );
00094 
00095     if( mode == XTEA_ENCRYPT )
00096     {
00097         uint32_t sum = 0, delta = 0x9E3779B9;
00098 
00099         for( i = 0; i < 32; i++ )
00100         {
00101             v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
00102             sum += delta;
00103             v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
00104         }
00105     }
00106     else /* XTEA_DECRYPT */
00107     {
00108         uint32_t delta = 0x9E3779B9, sum = delta * 32;
00109 
00110         for( i = 0; i < 32; i++ )
00111         {
00112             v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
00113             sum -= delta;
00114             v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
00115         }
00116     }
00117 
00118     PUT_UINT32_BE( v0, output, 0 );
00119     PUT_UINT32_BE( v1, output, 4 );
00120 
00121     return( 0 );
00122 }
00123 
00124 #if defined(POLARSSL_CIPHER_MODE_CBC)
00125 /*
00126  * XTEA-CBC buffer encryption/decryption
00127  */
00128 int xtea_crypt_cbc( xtea_context *ctx, int mode, size_t length,
00129                     unsigned char iv[8], const unsigned char *input,
00130                     unsigned char *output)
00131 {
00132     int i;
00133     unsigned char temp[8];
00134 
00135     if( length % 8 )
00136         return( POLARSSL_ERR_XTEA_INVALID_INPUT_LENGTH );
00137 
00138     if( mode == XTEA_DECRYPT )
00139     {
00140         while( length > 0 )
00141         {
00142             memcpy( temp, input, 8 );
00143             xtea_crypt_ecb( ctx, mode, input, output );
00144 
00145             for(i = 0; i < 8; i++)
00146                 output[i] = (unsigned char)( output[i] ^ iv[i] );
00147 
00148             memcpy( iv, temp, 8 );
00149 
00150             input  += 8;
00151             output += 8;
00152             length -= 8;
00153         }
00154     }
00155     else
00156     {
00157         while( length > 0 )
00158         {
00159             for( i = 0; i < 8; i++ )
00160                 output[i] = (unsigned char)( input[i] ^ iv[i] );
00161 
00162             xtea_crypt_ecb( ctx, mode, output, output );
00163             memcpy( iv, output, 8 );
00164 
00165             input  += 8;
00166             output += 8;
00167             length -= 8;
00168         }
00169     }
00170 
00171     return( 0 );
00172 }
00173 #endif /* POLARSSL_CIPHER_MODE_CBC */
00174 #endif /* !POLARSSL_XTEA_ALT */
00175 
00176 #if defined(POLARSSL_SELF_TEST)
00177 
00178 #include <string.h>
00179 #include <stdio.h>
00180 
00181 /*
00182  * XTEA tests vectors (non-official)
00183  */
00184 
00185 static const unsigned char xtea_test_key[6][16] =
00186 {
00187    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
00188      0x0c, 0x0d, 0x0e, 0x0f },
00189    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
00190      0x0c, 0x0d, 0x0e, 0x0f },
00191    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
00192      0x0c, 0x0d, 0x0e, 0x0f },
00193    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00194      0x00, 0x00, 0x00, 0x00 },
00195    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00196      0x00, 0x00, 0x00, 0x00 },
00197    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00198      0x00, 0x00, 0x00, 0x00 }
00199 };
00200 
00201 static const unsigned char xtea_test_pt[6][8] =
00202 {
00203     { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
00204     { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
00205     { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f },
00206     { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
00207     { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
00208     { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 }
00209 };
00210 
00211 static const unsigned char xtea_test_ct[6][8] =
00212 {
00213     { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 },
00214     { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 },
00215     { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
00216     { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 },
00217     { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d },
00218     { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }
00219 };
00220 
00221 /*
00222  * Checkup routine
00223  */
00224 int xtea_self_test( int verbose )
00225 {
00226     int i;
00227     unsigned char buf[8];
00228     xtea_context ctx;
00229 
00230     for( i = 0; i < 6; i++ )
00231     {
00232         if( verbose != 0 )
00233             polarssl_printf( "  XTEA test #%d: ", i + 1 );
00234 
00235         memcpy( buf, xtea_test_pt[i], 8 );
00236 
00237         xtea_setup( &ctx, xtea_test_key[i] );
00238         xtea_crypt_ecb( &ctx, XTEA_ENCRYPT, buf, buf );
00239 
00240         if( memcmp( buf, xtea_test_ct[i], 8 ) != 0 )
00241         {
00242             if( verbose != 0 )
00243                 polarssl_printf( "failed\n" );
00244 
00245             return( 1 );
00246         }
00247 
00248         if( verbose != 0 )
00249             polarssl_printf( "passed\n" );
00250     }
00251 
00252     if( verbose != 0 )
00253         polarssl_printf( "\n" );
00254 
00255     return( 0 );
00256 }
00257 
00258 #endif /* POLARSSL_SELF_TEST */
00259 
00260 #endif /* POLARSSL_XTEA_C */
00261 
00262