dolphin/Externals/mbedtls/library/xtea.c
Tillmann Karras 9872473f70 mbedTLS: add version 2.1.1
PolarSSL has been renamed to "mbed TLS" and version 2.0 dropped backwards
compatibility. This commit adds only the necessary files without any
modifications, so it doesn't compile yet.
2015-09-25 03:11:48 +02:00

282 lines
7.3 KiB
C

/*
* An 32-bit implementation of the XTEA algorithm
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif
#if defined(MBEDTLS_XTEA_C)
#include "mbedtls/xtea.h"
#include <string.h>
#if defined(MBEDTLS_SELF_TEST)
#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_PLATFORM_C */
#endif /* MBEDTLS_SELF_TEST */
#if !defined(MBEDTLS_XTEA_ALT)
/* Implementation that should never be optimized out by the compiler */
static void mbedtls_zeroize( void *v, size_t n ) {
volatile unsigned char *p = v; while( n-- ) *p++ = 0;
}
/*
* 32-bit integer manipulation macros (big endian)
*/
#ifndef GET_UINT32_BE
#define GET_UINT32_BE(n,b,i) \
{ \
(n) = ( (uint32_t) (b)[(i) ] << 24 ) \
| ( (uint32_t) (b)[(i) + 1] << 16 ) \
| ( (uint32_t) (b)[(i) + 2] << 8 ) \
| ( (uint32_t) (b)[(i) + 3] ); \
}
#endif
#ifndef PUT_UINT32_BE
#define PUT_UINT32_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
void mbedtls_xtea_init( mbedtls_xtea_context *ctx )
{
memset( ctx, 0, sizeof( mbedtls_xtea_context ) );
}
void mbedtls_xtea_free( mbedtls_xtea_context *ctx )
{
if( ctx == NULL )
return;
mbedtls_zeroize( ctx, sizeof( mbedtls_xtea_context ) );
}
/*
* XTEA key schedule
*/
void mbedtls_xtea_setup( mbedtls_xtea_context *ctx, const unsigned char key[16] )
{
int i;
memset( ctx, 0, sizeof(mbedtls_xtea_context) );
for( i = 0; i < 4; i++ )
{
GET_UINT32_BE( ctx->k[i], key, i << 2 );
}
}
/*
* XTEA encrypt function
*/
int mbedtls_xtea_crypt_ecb( mbedtls_xtea_context *ctx, int mode,
const unsigned char input[8], unsigned char output[8])
{
uint32_t *k, v0, v1, i;
k = ctx->k;
GET_UINT32_BE( v0, input, 0 );
GET_UINT32_BE( v1, input, 4 );
if( mode == MBEDTLS_XTEA_ENCRYPT )
{
uint32_t 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 /* MBEDTLS_XTEA_DECRYPT */
{
uint32_t 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_UINT32_BE( v0, output, 0 );
PUT_UINT32_BE( v1, output, 4 );
return( 0 );
}
#if defined(MBEDTLS_CIPHER_MODE_CBC)
/*
* XTEA-CBC buffer encryption/decryption
*/
int mbedtls_xtea_crypt_cbc( mbedtls_xtea_context *ctx, int mode, size_t length,
unsigned char iv[8], const unsigned char *input,
unsigned char *output)
{
int i;
unsigned char temp[8];
if( length % 8 )
return( MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH );
if( mode == MBEDTLS_XTEA_DECRYPT )
{
while( length > 0 )
{
memcpy( temp, input, 8 );
mbedtls_xtea_crypt_ecb( ctx, mode, input, output );
for( i = 0; i < 8; i++ )
output[i] = (unsigned char)( output[i] ^ iv[i] );
memcpy( iv, temp, 8 );
input += 8;
output += 8;
length -= 8;
}
}
else
{
while( length > 0 )
{
for( i = 0; i < 8; i++ )
output[i] = (unsigned char)( input[i] ^ iv[i] );
mbedtls_xtea_crypt_ecb( ctx, mode, output, output );
memcpy( iv, output, 8 );
input += 8;
output += 8;
length -= 8;
}
}
return( 0 );
}
#endif /* MBEDTLS_CIPHER_MODE_CBC */
#endif /* !MBEDTLS_XTEA_ALT */
#if defined(MBEDTLS_SELF_TEST)
/*
* 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 mbedtls_xtea_self_test( int verbose )
{
int i, ret = 0;
unsigned char buf[8];
mbedtls_xtea_context ctx;
mbedtls_xtea_init( &ctx );
for( i = 0; i < 6; i++ )
{
if( verbose != 0 )
mbedtls_printf( " XTEA test #%d: ", i + 1 );
memcpy( buf, xtea_test_pt[i], 8 );
mbedtls_xtea_setup( &ctx, xtea_test_key[i] );
mbedtls_xtea_crypt_ecb( &ctx, MBEDTLS_XTEA_ENCRYPT, buf, buf );
if( memcmp( buf, xtea_test_ct[i], 8 ) != 0 )
{
if( verbose != 0 )
mbedtls_printf( "failed\n" );
ret = 1;
goto exit;
}
if( verbose != 0 )
mbedtls_printf( "passed\n" );
}
if( verbose != 0 )
mbedtls_printf( "\n" );
exit:
mbedtls_xtea_free( &ctx );
return( ret );
}
#endif /* MBEDTLS_SELF_TEST */
#endif /* MBEDTLS_XTEA_C */