1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-28 00:58:09 +00:00

aes: update to newest version

This commit is contained in:
Pavol Rusnak 2018-08-14 13:05:21 +02:00
parent 5d62454c6a
commit d454a48b51
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
7 changed files with 72 additions and 248 deletions

View File

@ -15,7 +15,7 @@ This software is provided 'as is' with no explicit or implied warranties
in respect of its operation, including, but not limited to, correctness in respect of its operation, including, but not limited to, correctness
and fitness for purpose. and fitness for purpose.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Issue Date: 20/12/2007 Issue Date: 02/08/2018
This file contains the definitions required to use AES in C. See aesopt.h This file contains the definitions required to use AES in C. See aesopt.h
for optimisation details. for optimisation details.
@ -25,9 +25,13 @@ Issue Date: 20/12/2007
#define _AES_H #define _AES_H
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
/* This include is used to find 8 & 32 bit unsigned integer types */ #define VOID_RETURN void
#include "brg_types.h" #define INT_RETURN int
#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)))
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" extern "C"
@ -38,14 +42,21 @@ extern "C"
// #define AES_192 /* if a fast 192 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 */ #define AES_256 /* if a fast 256 bit key scheduler is needed */
// #define AES_VAR /* if variable key size scheduler is needed */ // #define AES_VAR /* if variable key size scheduler is needed */
#define AES_MODES /* if support is needed for modes */ #if 1
# define AES_MODES /* if support is needed for modes in the C code */
#endif /* (these will use AES_NI if it is present) */
#if 0 /* add this to make direct calls to the AES_NI */
# /* implemented CBC and CTR modes available */
# define ADD_AESNI_MODE_CALLS
#endif
/* The following must also be set in assembler files if being used */ /* The following must also be set in assembler files if being used */
#define AES_ENCRYPT /* if support for encryption is needed */ #define AES_ENCRYPT /* if support for encryption is needed */
#define AES_DECRYPT /* if support for decryption is needed */ #define AES_DECRYPT /* if support for decryption is needed */
#define AES_BLOCK_SIZE 16 /* the AES block size in bytes */ #define AES_BLOCK_SIZE_P2 4 /* AES block size as a power of 2 */
#define AES_BLOCK_SIZE (1 << AES_BLOCK_SIZE_P2) /* AES block size */
#define N_COLS 4 /* the number of columns in the state */ #define N_COLS 4 /* the number of columns in the state */
/* The key schedule length is 11, 13 or 15 16-byte blocks for 128, */ /* The key schedule length is 11, 13 or 15 16-byte blocks for 128, */

View File

@ -136,7 +136,7 @@ AES_RETURN aes_mode_reset(aes_encrypt_ctx ctx[1])
AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf, AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
int len, const aes_encrypt_ctx ctx[1]) int len, const aes_encrypt_ctx ctx[1])
{ int nb = len >> 4; { int nb = len >> AES_BLOCK_SIZE_P2;
if(len & (AES_BLOCK_SIZE - 1)) if(len & (AES_BLOCK_SIZE - 1))
return EXIT_FAILURE; return EXIT_FAILURE;
@ -198,7 +198,7 @@ AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf, AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
int len, const aes_decrypt_ctx ctx[1]) int len, const aes_decrypt_ctx ctx[1])
{ int nb = len >> 4; { int nb = len >> AES_BLOCK_SIZE_P2;
if(len & (AES_BLOCK_SIZE - 1)) if(len & (AES_BLOCK_SIZE - 1))
return EXIT_FAILURE; return EXIT_FAILURE;
@ -260,7 +260,7 @@ AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf, AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,
int len, unsigned char *iv, const aes_encrypt_ctx ctx[1]) int len, unsigned char *iv, const aes_encrypt_ctx ctx[1])
{ int nb = len >> 4; { int nb = len >> AES_BLOCK_SIZE_P2;
if(len & (AES_BLOCK_SIZE - 1)) if(len & (AES_BLOCK_SIZE - 1))
return EXIT_FAILURE; return EXIT_FAILURE;
@ -358,7 +358,7 @@ AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,
AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf, AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,
int len, unsigned char *iv, const aes_decrypt_ctx ctx[1]) int len, unsigned char *iv, const aes_decrypt_ctx ctx[1])
{ unsigned char tmp[AES_BLOCK_SIZE]; { unsigned char tmp[AES_BLOCK_SIZE];
int nb = len >> 4; int nb = len >> AES_BLOCK_SIZE_P2;
if(len & (AES_BLOCK_SIZE - 1)) if(len & (AES_BLOCK_SIZE - 1))
return EXIT_FAILURE; return EXIT_FAILURE;
@ -469,7 +469,7 @@ AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos); b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
} }
if((nb = (len - cnt) >> 4) != 0) /* process whole blocks */ if((nb = (len - cnt) >> AES_BLOCK_SIZE_P2) != 0) /* process whole blocks */
{ {
#if defined( USE_VIA_ACE_IF_PRESENT ) #if defined( USE_VIA_ACE_IF_PRESENT )
@ -597,7 +597,7 @@ AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos); b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
} }
if((nb = (len - cnt) >> 4) != 0) /* process whole blocks */ if((nb = (len - cnt) >> AES_BLOCK_SIZE_P2) != 0) /* process whole blocks */
{ {
#if defined( USE_VIA_ACE_IF_PRESENT ) #if defined( USE_VIA_ACE_IF_PRESENT )
@ -735,7 +735,7 @@ AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf,
b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos); b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
} }
if((nb = (len - cnt) >> 4) != 0) /* process whole blocks */ if((nb = (len - cnt) >> AES_BLOCK_SIZE_P2) != 0) /* process whole blocks */
{ {
#if defined( USE_VIA_ACE_IF_PRESENT ) #if defined( USE_VIA_ACE_IF_PRESENT )
@ -880,7 +880,7 @@ AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf,
{ {
blen = (len > BFR_LENGTH ? BFR_LENGTH : len), len -= blen; blen = (len > BFR_LENGTH ? BFR_LENGTH : len), len -= blen;
for(i = 0, ip = buf; i < (blen >> 4); ++i) for(i = 0, ip = buf; i < (blen >> AES_BLOCK_SIZE_P2); ++i)
{ {
memcpy(ip, cbuf, AES_BLOCK_SIZE); memcpy(ip, cbuf, AES_BLOCK_SIZE);
ctr_inc(cbuf); ctr_inc(cbuf);

View File

@ -55,7 +55,7 @@ extern "C"
so we need to control this with the following VC++ pragmas so we need to control this with the following VC++ pragmas
*/ */
#if defined( _MSC_VER ) && !defined( _WIN64 ) #if defined( _MSC_VER ) && !defined( _WIN64 ) && !defined( __clang__ )
#pragma optimize( "s", on ) #pragma optimize( "s", on )
#endif #endif
@ -101,7 +101,7 @@ AES_RETURN aes_xi(encrypt)(const unsigned char *in, unsigned char *out, const ae
dec_fmvars; /* declare variables for fwd_mcol() if needed */ dec_fmvars; /* declare variables for fwd_mcol() if needed */
#endif #endif
if(cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16) if(cx->inf.b[0] != 10 * AES_BLOCK_SIZE && cx->inf.b[0] != 12 * AES_BLOCK_SIZE && cx->inf.b[0] != 14 * AES_BLOCK_SIZE)
return EXIT_FAILURE; return EXIT_FAILURE;
kp = cx->ks; kp = cx->ks;
@ -111,17 +111,17 @@ AES_RETURN aes_xi(encrypt)(const unsigned char *in, unsigned char *out, const ae
switch(cx->inf.b[0]) switch(cx->inf.b[0])
{ {
case 14 * 16: case 14 * AES_BLOCK_SIZE:
round(fwd_rnd, b1, b0, kp + 1 * N_COLS); round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
round(fwd_rnd, b0, b1, kp + 2 * N_COLS); round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
kp += 2 * N_COLS; kp += 2 * N_COLS;
//-fallthrough //-fallthrough
case 12 * 16: case 12 * AES_BLOCK_SIZE:
round(fwd_rnd, b1, b0, kp + 1 * N_COLS); round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
round(fwd_rnd, b0, b1, kp + 2 * N_COLS); round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
kp += 2 * N_COLS; kp += 2 * N_COLS;
//-fallthrough //-fallthrough
case 10 * 16: case 10 * AES_BLOCK_SIZE:
round(fwd_rnd, b1, b0, kp + 1 * N_COLS); round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
round(fwd_rnd, b0, b1, kp + 2 * N_COLS); round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
round(fwd_rnd, b1, b0, kp + 3 * N_COLS); round(fwd_rnd, b1, b0, kp + 3 * N_COLS);
@ -175,7 +175,7 @@ AES_RETURN aes_xi(encrypt)(const unsigned char *in, unsigned char *out, const ae
so we need to control this with the following VC++ pragmas so we need to control this with the following VC++ pragmas
*/ */
#if defined( _MSC_VER ) && !defined( _WIN64 ) #if defined( _MSC_VER ) && !defined( _WIN64 ) && !defined( __clang__ )
#pragma optimize( "t", on ) #pragma optimize( "t", on )
#endif #endif
@ -236,7 +236,7 @@ AES_RETURN aes_xi(decrypt)(const unsigned char *in, unsigned char *out, const ae
#endif #endif
const uint32_t *kp; const uint32_t *kp;
if(cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16) if(cx->inf.b[0] != 10 * AES_BLOCK_SIZE && cx->inf.b[0] != 12 * AES_BLOCK_SIZE && cx->inf.b[0] != 14 * AES_BLOCK_SIZE)
return EXIT_FAILURE; return EXIT_FAILURE;
kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0); kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
@ -247,15 +247,15 @@ AES_RETURN aes_xi(decrypt)(const unsigned char *in, unsigned char *out, const ae
kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2)); kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
switch(cx->inf.b[0]) switch(cx->inf.b[0])
{ {
case 14 * 16: case 14 * AES_BLOCK_SIZE:
round(inv_rnd, b1, b0, rnd_key(-13)); round(inv_rnd, b1, b0, rnd_key(-13));
round(inv_rnd, b0, b1, rnd_key(-12)); round(inv_rnd, b0, b1, rnd_key(-12));
//-fallthrough //-fallthrough
case 12 * 16: case 12 * AES_BLOCK_SIZE:
round(inv_rnd, b1, b0, rnd_key(-11)); round(inv_rnd, b1, b0, rnd_key(-11));
round(inv_rnd, b0, b1, rnd_key(-10)); round(inv_rnd, b0, b1, rnd_key(-10));
//-fallthrough //-fallthrough
case 10 * 16: case 10 * AES_BLOCK_SIZE:
round(inv_rnd, b1, b0, rnd_key(-9)); round(inv_rnd, b1, b0, rnd_key(-9));
round(inv_rnd, b0, b1, rnd_key(-8)); round(inv_rnd, b0, b1, rnd_key(-8));
round(inv_rnd, b1, b0, rnd_key(-7)); round(inv_rnd, b1, b0, rnd_key(-7));

View File

@ -101,7 +101,7 @@ AES_RETURN aes_xi(encrypt_key128)(const unsigned char *key, aes_encrypt_ctx cx[1
#endif #endif
ke4(cx->ks, 9); ke4(cx->ks, 9);
cx->inf.l = 0; cx->inf.l = 0;
cx->inf.b[0] = 10 * 16; cx->inf.b[0] = 10 * AES_BLOCK_SIZE;
#ifdef USE_VIA_ACE_IF_PRESENT #ifdef USE_VIA_ACE_IF_PRESENT
if(VIA_ACE_AVAILABLE) if(VIA_ACE_AVAILABLE)
@ -150,7 +150,7 @@ AES_RETURN aes_xi(encrypt_key192)(const unsigned char *key, aes_encrypt_ctx cx[1
#endif #endif
kef6(cx->ks, 7); kef6(cx->ks, 7);
cx->inf.l = 0; cx->inf.l = 0;
cx->inf.b[0] = 12 * 16; cx->inf.b[0] = 12 * AES_BLOCK_SIZE;
#ifdef USE_VIA_ACE_IF_PRESENT #ifdef USE_VIA_ACE_IF_PRESENT
if(VIA_ACE_AVAILABLE) if(VIA_ACE_AVAILABLE)
@ -202,7 +202,7 @@ AES_RETURN aes_xi(encrypt_key256)(const unsigned char *key, aes_encrypt_ctx cx[1
#endif #endif
kef8(cx->ks, 6); kef8(cx->ks, 6);
cx->inf.l = 0; cx->inf.l = 0;
cx->inf.b[0] = 14 * 16; cx->inf.b[0] = 14 * AES_BLOCK_SIZE;
#ifdef USE_VIA_ACE_IF_PRESENT #ifdef USE_VIA_ACE_IF_PRESENT
if(VIA_ACE_AVAILABLE) if(VIA_ACE_AVAILABLE)
@ -329,7 +329,7 @@ AES_RETURN aes_xi(decrypt_key128)(const unsigned char *key, aes_decrypt_ctx cx[1
} }
#endif #endif
cx->inf.l = 0; cx->inf.l = 0;
cx->inf.b[0] = 10 * 16; cx->inf.b[0] = 10 * AES_BLOCK_SIZE;
#ifdef USE_VIA_ACE_IF_PRESENT #ifdef USE_VIA_ACE_IF_PRESENT
if(VIA_ACE_AVAILABLE) if(VIA_ACE_AVAILABLE)
@ -395,7 +395,6 @@ AES_RETURN aes_xi(decrypt_key192)(const unsigned char *key, aes_decrypt_ctx cx[1
#ifdef DEC_KS_UNROLL #ifdef DEC_KS_UNROLL
ss[4] = word_in(key, 4); ss[4] = word_in(key, 4);
ss[5] = word_in(key, 5); ss[5] = word_in(key, 5);
cx->ks[v(48,(4))] = ff(ss[4]); cx->ks[v(48,(4))] = ff(ss[4]);
cx->ks[v(48,(5))] = ff(ss[5]); cx->ks[v(48,(5))] = ff(ss[5]);
kdf6(cx->ks, 0); kd6(cx->ks, 1); kdf6(cx->ks, 0); kd6(cx->ks, 1);
@ -417,7 +416,7 @@ AES_RETURN aes_xi(decrypt_key192)(const unsigned char *key, aes_decrypt_ctx cx[1
} }
#endif #endif
cx->inf.l = 0; cx->inf.l = 0;
cx->inf.b[0] = 12 * 16; cx->inf.b[0] = 12 * AES_BLOCK_SIZE;
#ifdef USE_VIA_ACE_IF_PRESENT #ifdef USE_VIA_ACE_IF_PRESENT
if(VIA_ACE_AVAILABLE) if(VIA_ACE_AVAILABLE)
@ -492,7 +491,6 @@ AES_RETURN aes_xi(decrypt_key256)(const unsigned char *key, aes_decrypt_ctx cx[1
ss[5] = word_in(key, 5); ss[5] = word_in(key, 5);
ss[6] = word_in(key, 6); ss[6] = word_in(key, 6);
ss[7] = word_in(key, 7); ss[7] = word_in(key, 7);
cx->ks[v(56,(4))] = ff(ss[4]); cx->ks[v(56,(4))] = ff(ss[4]);
cx->ks[v(56,(5))] = ff(ss[5]); cx->ks[v(56,(5))] = ff(ss[5]);
cx->ks[v(56,(6))] = ff(ss[6]); cx->ks[v(56,(6))] = ff(ss[6]);
@ -518,7 +516,7 @@ AES_RETURN aes_xi(decrypt_key256)(const unsigned char *key, aes_decrypt_ctx cx[1
} }
#endif #endif
cx->inf.l = 0; cx->inf.l = 0;
cx->inf.b[0] = 14 * 16; cx->inf.b[0] = 14 * AES_BLOCK_SIZE;
#ifdef USE_VIA_ACE_IF_PRESENT #ifdef USE_VIA_ACE_IF_PRESENT
if(VIA_ACE_AVAILABLE) if(VIA_ACE_AVAILABLE)

View File

@ -64,7 +64,7 @@ Issue Date: 20/12/2007
Class AESencrypt for encryption Class AESencrypt for encryption
Construtors: Constructors:
AESencrypt(void) AESencrypt(void)
AESencrypt(const unsigned char *key) - 128 bit key AESencrypt(const unsigned char *key) - 128 bit key
Members: Members:
@ -74,7 +74,7 @@ Issue Date: 20/12/2007
AES_RETURN encrypt(const unsigned char *in, unsigned char *out) const AES_RETURN encrypt(const unsigned char *in, unsigned char *out) const
Class AESdecrypt for encryption Class AESdecrypt for encryption
Construtors: Constructors:
AESdecrypt(void) AESdecrypt(void)
AESdecrypt(const unsigned char *key) - 128 bit key AESdecrypt(const unsigned char *key) - 128 bit key
Members: Members:
@ -165,16 +165,21 @@ Issue Date: 20/12/2007
/* 2. Intel AES AND VIA ACE SUPPORT */ /* 2. Intel AES AND VIA ACE SUPPORT */
#if defined( __GNUC__ ) && defined( __i386__ ) \ #if defined( __GNUC__ ) && defined( __i386__ ) && !defined(__BEOS__) \
|| defined( _WIN32 ) && defined( _M_IX86 ) && !(defined( _WIN64 ) \ || defined( _WIN32 ) && defined( _M_IX86 ) && !(defined( _WIN64 ) \
|| defined( _WIN32_WCE ) || defined( _MSC_VER ) && ( _MSC_VER <= 800 )) || defined( _WIN32_WCE ) || defined( _MSC_VER ) && ( _MSC_VER <= 800 ))
# define VIA_ACE_POSSIBLE # define VIA_ACE_POSSIBLE
#endif #endif
#if (defined( _WIN64 ) && defined( _MSC_VER )) \ /* AESNI is supported by all Windows x64 compilers, but for Linux/GCC
|| (defined( __GNUC__ ) && defined( __x86_64__ )) \ we have to test for SSE 2, SSE 3, and AES to before enabling it; */
&& !(defined( INTEL_AES_POSSIBLE )) #if !defined( INTEL_AES_POSSIBLE )
# if defined( _WIN64 ) && defined( _MSC_VER ) \
|| defined( __GNUC__ ) && defined( __x86_64__ ) && \
defined( __SSE2__ ) && defined( __SSE3__ ) && \
defined( __AES__ )
# define INTEL_AES_POSSIBLE # define INTEL_AES_POSSIBLE
# endif
#endif #endif
/* Define this option if support for the Intel AESNI is required /* Define this option if support for the Intel AESNI is required
@ -184,10 +189,11 @@ Issue Date: 20/12/2007
AESNI uses a decryption key schedule with the first decryption AESNI uses a decryption key schedule with the first decryption
round key at the high end of the key scedule with the following 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 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 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 assembler code will be used with an AESNI build, if it is then
AES_REV_DKS must NOT be defined when the assembler files are AES_REV_DKS must NOT be defined when the assembler files are
built built (the definition of USE_INTEL_AES_IF_PRESENT in the assembler
code files must match that here if they are used).
*/ */
#if 0 && defined( INTEL_AES_POSSIBLE ) && !defined( USE_INTEL_AES_IF_PRESENT ) #if 0 && defined( INTEL_AES_POSSIBLE ) && !defined( USE_INTEL_AES_IF_PRESENT )

View File

@ -78,8 +78,8 @@ Issue Date: 20/12/2007
#define do_enc(a,b,c,d) f_enc_blk(a, b, c) #define do_enc(a,b,c,d) f_enc_blk(a, b, c)
#define do_dec(a,b,c,d) f_dec_blk(a, b, c) #define do_dec(a,b,c,d) f_dec_blk(a, b, c)
#else #else
#define do_enc(a,b,c,d) f_ecb_enc(a, b, c, AES_BLOCK_SIZE) #define do_enc(a,b,c,d) f_ecb_enc(a, b, c, 1)
#define do_dec(a,b,c,d) f_ecb_dec(a, b, c, AES_BLOCK_SIZE) #define do_dec(a,b,c,d) f_ecb_dec(a, b, c, 1)
#endif #endif
#endif #endif

View File

@ -1,191 +0,0 @@
/*
---------------------------------------------------------------------------
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