diff --git a/aes/aes.h b/aes/aes.h index 524f4c0f5..8cc0526ae 100644 --- a/aes/aes.h +++ b/aes/aes.h @@ -25,17 +25,15 @@ Issue Date: 20/12/2007 #define _AES_H #include -#include + +/* This include is used to find 8 & 32 bit unsigned integer types */ +#include "brg_types.h" #if defined(__cplusplus) extern "C" { #endif -#define ALIGN_OFFSET(x,n) (((intptr_t)(x)) & ((n) - 1)) -#define ALIGN_FLOOR(x,n) ((uint8_t*)(x) - ( ((intptr_t)(x)) & ((n) - 1))) -#define ALIGN_CEIL(x,n) ((uint8_t*)(x) + (-((intptr_t)(x)) & ((n) - 1))) - // #define AES_128 /* if a fast 128 bit key scheduler is needed */ // #define AES_192 /* if a fast 192 bit key scheduler is needed */ #define AES_256 /* if a fast 256 bit key scheduler is needed */ @@ -62,7 +60,7 @@ extern "C" #define KS_LENGTH 44 #endif -#define AES_RETURN int +#define AES_RETURN INT_RETURN /* the character array 'inf' in the following structures is used */ /* to hold AES context information. This AES code uses cx->inf.b[0] */ @@ -74,22 +72,32 @@ typedef union uint8_t b[4]; } aes_inf; -#ifdef _WIN64 -__declspec(align(16)) -#endif -typedef struct +#ifdef _MSC_VER +# pragma warning( disable : 4324 ) +#endif + +#if defined(_MSC_VER) && defined(_WIN64) +#define ALIGNED_(x) __declspec(align(x)) +#elif defined(__GNUC__) && defined(__x86_64__) +#define ALIGNED_(x) __attribute__ ((aligned(x))) +#else +#define ALIGNED_(x) +#endif + +typedef struct ALIGNED_(16) { uint32_t ks[KS_LENGTH]; aes_inf inf; } aes_encrypt_ctx; -#ifdef _WIN64 -__declspec(align(16)) -#endif -typedef struct +typedef struct ALIGNED_(16) { uint32_t ks[KS_LENGTH]; aes_inf inf; } aes_decrypt_ctx; +#ifdef _MSC_VER +# pragma warning( default : 4324 ) +#endif + /* This routine must be called before first use if non-static */ /* tables are being used */ @@ -151,9 +159,9 @@ AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_de /* each individual call within a series of incremental calls must */ /* process only full blocks (i.e. len must be a multiple of 16) but */ /* the CFB, OFB and CTR mode calls can handle multiple incremental */ -/* calls of any length. Each mode is reset when a new AES key is */ -/* set but ECB and CBC operations can be reset without setting a */ -/* new key by setting a new IV value. To reset CFB, OFB and CTR */ +/* calls of any length. Each mode is reset when a new AES key is */ +/* set but ECB needs no reset and CBC can be reset without setting */ +/* a new key by setting a new IV value. To reset CFB, OFB and CTR */ /* without setting the key, aes_mode_reset() must be called and the */ /* IV must be set. NOTE: All these calls update the IV on exit so */ /* this has to be reset if a new operation with the same IV as the */ diff --git a/aes/aes_modes.c b/aes/aes_modes.c index 2a432c804..744395e0e 100644 --- a/aes/aes_modes.c +++ b/aes/aes_modes.c @@ -943,12 +943,12 @@ AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf, void aes_ctr_cbuf_inc(unsigned char *cbuf) { - int i = 15; - while (i >= 0) { - cbuf[i]++; - if (cbuf[i]) return; // if there was no overflow - i--; - } + int i = AES_BLOCK_SIZE - 1; + while (i >= 0) { + cbuf[i]++; + if (cbuf[i]) return; // if there was no overflow + i--; + } } #if defined(__cplusplus) diff --git a/aes/aesopt.h b/aes/aesopt.h index ee96215b2..a1ef045df 100644 --- a/aes/aesopt.h +++ b/aes/aesopt.h @@ -87,7 +87,11 @@ Issue Date: 20/12/2007 #if !defined( _AESOPT_H ) #define _AESOPT_H +#if defined( __cplusplus ) +#include "aescpp.h" +#else #include "aes.h" +#endif /* PLATFORM SPECIFIC INCLUDES */ @@ -162,30 +166,31 @@ Issue Date: 20/12/2007 /* 2. Intel AES AND VIA ACE SUPPORT */ #if defined( __GNUC__ ) && defined( __i386__ ) \ - || defined(_WIN32) && defined(_M_IX86) \ - && !(defined(_WIN64) || defined(_WIN32_WCE) || defined(_MSC_VER) && (_MSC_VER <= 800)) + || defined( _WIN32 ) && defined( _M_IX86 ) && !(defined( _WIN64 ) \ + || defined( _WIN32_WCE ) || defined( _MSC_VER ) && ( _MSC_VER <= 800 )) # define VIA_ACE_POSSIBLE #endif -/* Define this option if support for the Intel AESNI is required (not - currently available with GCC). If AESNI is known to be present, then - defining ASSUME_INTEL_AES_VIA_PRESENT will replace the ordinary - encryption/decryption. If USE_INTEL_AES_IF_PRESENT is defined then - AESNI will be used if it is detected (both present and enabled). +#if (defined( _WIN64 ) && defined( _MSC_VER )) \ + || (defined( __GNUC__ ) && defined( __x86_64__ )) \ + && !(defined( INTEL_AES_POSSIBLE )) +# define INTEL_AES_POSSIBLE +#endif + +/* Define this option if support for the Intel AESNI is required + If USE_INTEL_AES_IF_PRESENT is defined then AESNI will be used + if it is detected (both present and enabled). AESNI uses a decryption key schedule with the first decryption round key at the high end of the key scedule with the following round keys at lower positions in memory. So AES_REV_DKS must NOT be defined when AESNI will be used. ALthough it is unlikely that assembler code will be used with an AESNI build, if it is then - AES_REV_DKS must NOT be defined when such assembler files are + AES_REV_DKS must NOT be defined when the assembler files are built */ -#if 0 && defined( _WIN64 ) && defined( _MSC_VER ) -# define INTEL_AES_POSSIBLE -#endif -#if defined( INTEL_AES_POSSIBLE ) && !defined( USE_INTEL_AES_IF_PRESENT ) +#if 0 && defined( INTEL_AES_POSSIBLE ) && !defined( USE_INTEL_AES_IF_PRESENT ) # define USE_INTEL_AES_IF_PRESENT #endif @@ -243,8 +248,14 @@ Issue Date: 20/12/2007 # define ASM_AMD64_C #endif +#if defined( __i386 ) || defined( _M_IX86 ) +# define A32_ +#elif defined( __x86_64__ ) || defined( _M_X64 ) +# define A64_ +#endif + #if (defined ( ASM_X86_V1C ) || defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )) \ - && !defined( _M_IX86 ) || defined( ASM_AMD64_C ) && !defined( _M_X64 ) + && !defined( A32_ ) || defined( ASM_AMD64_C ) && !defined( A64_ ) # error Assembler code is only available for x86 and AMD64 systems #endif @@ -306,7 +317,7 @@ Issue Date: 20/12/2007 /* 6. FAST FINITE FIELD OPERATIONS If this section is included, tables are used to provide faster finite - field arithmetic (this has no effect if FIXED_TABLES is defined). + field arithmetic (this has no effect if STATIC_TABLES is defined). */ #if 1 # define FF_TABLES @@ -330,12 +341,12 @@ Issue Date: 20/12/2007 must be called to compute them before the code is first used. */ #if 1 && !(defined( _MSC_VER ) && ( _MSC_VER <= 800 )) -# define FIXED_TABLES +# define STATIC_TABLES #endif /* 9. MASKING OR CASTING FROM LONGER VALUES TO BYTES - In some systems it is better to mask longer values to extract bytes + In some systems it is better to mask longer values to extract bytes rather than using a cast. This option allows this choice. */ #if 0 @@ -676,7 +687,7 @@ Issue Date: 20/12/2007 #if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))) # if ((FUNCS_IN_C & ENC_KEYING_IN_C) || (FUNCS_IN_C & DEC_KEYING_IN_C)) # if KEY_SCHED == ONE_TABLE -# if !defined( FL1_SET ) && !defined( FL4_SET ) +# if !defined( FL1_SET ) && !defined( FL4_SET ) # define LS1_SET # endif # elif KEY_SCHED == FOUR_TABLES @@ -725,7 +736,7 @@ Issue Date: 20/12/2007 /* perform forward and inverse column mix operation on four bytes in long word x in */ /* parallel. NOTE: x must be a simple variable, NOT an expression in these macros. */ -#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))) +#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))) #if defined( FM4_SET ) /* not currently used */ # define fwd_mcol(x) four_tables(x,t_use(f,m),vf1,rf1,0) diff --git a/aes/aestab.c b/aes/aestab.c index 8fd11f94a..3d48edf3e 100644 --- a/aes/aestab.c +++ b/aes/aestab.c @@ -23,7 +23,7 @@ Issue Date: 20/12/2007 #include "aes.h" #include "aesopt.h" -#if defined(FIXED_TABLES) +#if defined(STATIC_TABLES) #define sb_data(w) {\ w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\ @@ -150,7 +150,7 @@ Issue Date: 20/12/2007 #endif -#if defined(FIXED_TABLES) || !defined(FF_TABLES) +#if defined(STATIC_TABLES) || !defined(FF_TABLES) #define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY)) #define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY)) @@ -180,7 +180,7 @@ extern "C" { #endif -#if defined(FIXED_TABLES) +#if defined(STATIC_TABLES) /* implemented in case of wrong call for fixed tables */ @@ -195,7 +195,7 @@ AES_RETURN aes_init(void) #define gf_inv(x) ((x) ? pow[ 255 - log[x]] : 0) -#else +#else /* It will generally be sensible to use tables to compute finite field multiplies and inverses but where memory is scarse this @@ -221,7 +221,7 @@ static uint8_t hibit(const uint32_t x) static uint8_t gf_inv(const uint8_t x) { uint8_t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0; - if(x < 2) + if(x < 2) return x; for( ; ; ) @@ -229,20 +229,20 @@ static uint8_t gf_inv(const uint8_t x) if(n1) while(n2 >= n1) /* divide polynomial p2 by p1 */ { - n2 /= n1; /* shift smaller polynomial left */ + n2 /= n1; /* shift smaller polynomial left */ p2 ^= (p1 * n2) & 0xff; /* and remove from larger one */ - v2 ^= v1 * n2; /* shift accumulated value and */ + v2 ^= v1 * n2; /* shift accumulated value and */ n2 = hibit(p2); /* add into result */ } else return v1; - if(n2) /* repeat with values swapped */ + if(n2) /* repeat with values swapped */ while(n1 >= n2) { - n1 /= n2; - p1 ^= p2 * n1; - v1 ^= v2 * n1; + n1 /= n2; + p1 ^= p2 * n1; + v1 ^= v2 * n1; n1 = hibit(p1); } else @@ -383,6 +383,33 @@ AES_RETURN aes_init(void) return EXIT_SUCCESS; } +/* + Automatic code initialisation (suggested by by Henrik S. Gaßmann) + based on code provided by Joe Lowe and placed in the public domain at: + http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc +*/ + +#ifdef _MSC_VER + +#pragma section(".CRT$XCU", read) + +__declspec(allocate(".CRT$XCU")) void (__cdecl *aes_startup)(void) = aes_init; + +#elif defined(__GNUC__) + +static void aes_startup(void) __attribute__((constructor)); + +static void aes_startup(void) +{ + aes_init(); +} + +#else + +#pragma message( "dynamic tables must be initialised manually on your system" ) + +#endif + #endif #if defined(__cplusplus) diff --git a/aes/aestab.h b/aes/aestab.h index 46719d330..8fe32d180 100644 --- a/aes/aestab.h +++ b/aes/aestab.h @@ -29,7 +29,7 @@ Issue Date: 20/12/2007 that control the calls to aes_init() and the aes_init() routine itself will have to be changed for a specific implementation. If global variables are available it will generally be preferable to use them with the precomputed - FIXED_TABLES option that uses static global tables. + STATIC_TABLES option that uses static global tables. The following defines can be used to control the way the tables are defined, initialised and used in embedded environments that @@ -69,7 +69,7 @@ extern "C" { #define t_set(m,n) t_##m##n #define t_use(m,n) t_##m##n -#if defined(FIXED_TABLES) +#if defined(STATIC_TABLES) # if !defined( __GNUC__ ) && (defined( __MSDOS__ ) || defined( __WIN16__ )) /* make tables far data to avoid using too much DGROUP space (PG) */ # define CONST const far @@ -98,7 +98,7 @@ extern "C" { # define XP_DIR #endif -#if defined(DO_TABLES) && defined(FIXED_TABLES) +#if defined(DO_TABLES) && defined(STATIC_TABLES) #define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256] = b(e) #define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256] = { b(e), b(f), b(g), b(h) } EXTERN ALIGN CONST uint32_t t_dec(r,c)[RC_LENGTH] = rc_data(w0); diff --git a/aes/brg_types.h b/aes/brg_types.h new file mode 100644 index 000000000..307319bf6 --- /dev/null +++ b/aes/brg_types.h @@ -0,0 +1,191 @@ +/* +--------------------------------------------------------------------------- +Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. + +The redistribution and use of this software (with or without changes) +is allowed without the payment of fees or royalties provided that: + + source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation. + +This software is provided 'as is' with no explicit or implied warranties +in respect of its operation, including, but not limited to, correctness +and fitness for purpose. +--------------------------------------------------------------------------- +Issue Date: 20/12/2007 + + The unsigned integer types defined here are of the form uint_t where + is the length of the type; for example, the unsigned 32-bit type is + 'uint32_t'. These are NOT the same as the 'C99 integer types' that are + defined in the inttypes.h and stdint.h headers since attempts to use these + types have shown that support for them is still highly variable. However, + since the latter are of the form uint_t, a regular expression search + and replace (in VC++ search on 'uint_{:z}t' and replace with 'uint\1_t') + can be used to convert the types used here to the C99 standard types. +*/ + +#ifndef _BRG_TYPES_H +#define _BRG_TYPES_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include +#include + +#if defined( _MSC_VER ) && ( _MSC_VER >= 1300 ) +# include +# define ptrint_t intptr_t +#elif defined( __ECOS__ ) +# define intptr_t unsigned int +# define ptrint_t intptr_t +#elif defined( __GNUC__ ) && ( __GNUC__ >= 3 ) +# define ptrint_t intptr_t +#else +# define ptrint_t int +#endif + +#ifndef BRG_UI32 +# define BRG_UI32 +# if UINT_MAX == 4294967295u +# define li_32(h) 0x##h##u +# elif ULONG_MAX == 4294967295u +# define li_32(h) 0x##h##ul +# elif defined( _CRAY ) +# error This code needs 32-bit data types, which Cray machines do not provide +# else +# error Please define uint32_t as a 32-bit unsigned integer type in brg_types.h +# endif +#endif + +#ifndef BRG_UI64 +# if defined( __BORLANDC__ ) && !defined( __MSDOS__ ) +# define BRG_UI64 +# define li_64(h) 0x##h##ui64 +# elif defined( _MSC_VER ) && ( _MSC_VER < 1300 ) /* 1300 == VC++ 7.0 */ +# define BRG_UI64 +# define li_64(h) 0x##h##ui64 +# elif defined( __sun ) && defined( ULONG_MAX ) && ULONG_MAX == 0xfffffffful +# define BRG_UI64 +# define li_64(h) 0x##h##ull +# elif defined( __MVS__ ) +# define BRG_UI64 +# define li_64(h) 0x##h##ull +# elif defined( UINT_MAX ) && UINT_MAX > 4294967295u +# if UINT_MAX == 18446744073709551615u +# define BRG_UI64 +# define li_64(h) 0x##h##u +# endif +# elif defined( ULONG_MAX ) && ULONG_MAX > 4294967295u +# if ULONG_MAX == 18446744073709551615ul +# define BRG_UI64 +# define li_64(h) 0x##h##ul +# endif +# elif defined( ULLONG_MAX ) && ULLONG_MAX > 4294967295u +# if ULLONG_MAX == 18446744073709551615ull +# define BRG_UI64 +# define li_64(h) 0x##h##ull +# endif +# elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX > 4294967295u +# if ULONG_LONG_MAX == 18446744073709551615ull +# define BRG_UI64 +# define li_64(h) 0x##h##ull +# endif +# endif +#endif + +#if !defined( BRG_UI64 ) +# if defined( NEED_UINT_64T ) +# error Please define uint64_t as an unsigned 64 bit type in brg_types.h +# endif +#endif + +#ifndef RETURN_VALUES +# define RETURN_VALUES +# if defined( DLL_EXPORT ) +# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER ) +# define VOID_RETURN __declspec( dllexport ) void __stdcall +# define INT_RETURN __declspec( dllexport ) int __stdcall +# elif defined( __GNUC__ ) +# define VOID_RETURN __declspec( __dllexport__ ) void +# define INT_RETURN __declspec( __dllexport__ ) int +# else +# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers +# endif +# elif defined( DLL_IMPORT ) +# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER ) +# define VOID_RETURN __declspec( dllimport ) void __stdcall +# define INT_RETURN __declspec( dllimport ) int __stdcall +# elif defined( __GNUC__ ) +# define VOID_RETURN __declspec( __dllimport__ ) void +# define INT_RETURN __declspec( __dllimport__ ) int +# else +# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers +# endif +# elif defined( __WATCOMC__ ) +# define VOID_RETURN void __cdecl +# define INT_RETURN int __cdecl +# else +# define VOID_RETURN void +# define INT_RETURN int +# endif +#endif + +/* These defines are used to detect and set the memory alignment of pointers. + Note that offsets are in bytes. + + ALIGN_OFFSET(x,n) return the positive or zero offset of + the memory addressed by the pointer 'x' + from an address that is aligned on an + 'n' byte boundary ('n' is a power of 2) + + ALIGN_FLOOR(x,n) return a pointer that points to memory + that is aligned on an 'n' byte boundary + and is not higher than the memory address + pointed to by 'x' ('n' is a power of 2) + + ALIGN_CEIL(x,n) return a pointer that points to memory + that is aligned on an 'n' byte boundary + and is not lower than the memory address + pointed to by 'x' ('n' is a power of 2) +*/ + +#define ALIGN_OFFSET(x,n) (((ptrint_t)(x)) & ((n) - 1)) +#define ALIGN_FLOOR(x,n) ((uint8_t*)(x) - ( ((ptrint_t)(x)) & ((n) - 1))) +#define ALIGN_CEIL(x,n) ((uint8_t*)(x) + (-((ptrint_t)(x)) & ((n) - 1))) + +/* These defines are used to declare buffers in a way that allows + faster operations on longer variables to be used. In all these + defines 'size' must be a power of 2 and >= 8. NOTE that the + buffer size is in bytes but the type length is in bits + + UNIT_TYPEDEF(x,size) declares a variable 'x' of length + 'size' bits + + BUFR_TYPEDEF(x,size,bsize) declares a buffer 'x' of length 'bsize' + bytes defined as an array of variables + each of 'size' bits (bsize must be a + multiple of size / 8) + + UNIT_CAST(x,size) casts a variable to a type of + length 'size' bits + + UPTR_CAST(x,size) casts a pointer to a pointer to a + varaiable of length 'size' bits +*/ + +#define UI_TYPE(size) uint##size##_t +#define UNIT_TYPEDEF(x,size) typedef UI_TYPE(size) x +#define BUFR_TYPEDEF(x,size,bsize) typedef UI_TYPE(size) x[bsize / (size >> 3)] +#define UNIT_CAST(x,size) ((UI_TYPE(size) )(x)) +#define UPTR_CAST(x,size) ((UI_TYPE(size)*)(x)) + +#if defined(__cplusplus) +} +#endif + +#endif