1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-12 18:49:07 +00:00

update AES code from Github

This commit is contained in:
Pavol Rusnak 2017-05-08 17:08:48 +02:00
parent ca3423efc3
commit 2ae032adbb
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
6 changed files with 292 additions and 55 deletions

View File

@ -25,17 +25,15 @@ Issue Date: 20/12/2007
#define _AES_H
#include <stdlib.h>
#include <stdint.h>
/* 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 */

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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);

191
aes/brg_types.h Normal file
View File

@ -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_<nn>t where
<nn> 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<nn>_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 <limits.h>
#include <stdint.h>
#if defined( _MSC_VER ) && ( _MSC_VER >= 1300 )
# include <stddef.h>
# 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