IBR-DTNSuite  0.8
ibrcommon/ibrcommon/ssl/gcm/mode_hdr.h
Go to the documentation of this file.
00001 /*
00002  ---------------------------------------------------------------------------
00003  Copyright (c) 1998-2006, Brian Gladman, Worcester, UK. All rights reserved.
00004 
00005  LICENSE TERMS
00006 
00007  The free distribution and use of this software in both source and binary
00008  form is allowed (with or without changes) provided that:
00009 
00010    1. distributions of this source code include the above copyright
00011       notice, this list of conditions and the following disclaimer;
00012 
00013    2. distributions in binary form include the above copyright
00014       notice, this list of conditions and the following disclaimer
00015       in the documentation and/or other associated materials;
00016 
00017    3. the copyright holder's name is not used to endorse products
00018       built using this software without specific written permission.
00019 
00020  ALTERNATIVELY, provided that this notice is retained in full, this product
00021  may be distributed under the terms of the GNU General Public License (GPL),
00022  in which case the provisions of the GPL apply INSTEAD OF those given above.
00023 
00024  DISCLAIMER
00025 
00026  This software is provided 'as is' with no explicit or implied warranties
00027  in respect of its properties, including, but not limited to, correctness
00028  and/or fitness for purpose.
00029  ---------------------------------------------------------------------------
00030  Issue Date: 13/10/2006
00031 
00032  This header file is an INTERNAL file which supports mode implementation
00033 */
00034 
00035 /*  This file changed 5 June 2007 to reflect name change  
00036     of included file from "aes.h" to "gcm_aes.h"
00037     Changed by Peter Lovell, SPARTA Inc., for DTN project.
00038 */
00039 
00040 #ifndef _MODE_HDR_H
00041 #define _MODE_HDR_H
00042 
00043 /*  This define sets the units in which buffers are processed.  This code
00044     can provide significant speed gains if buffers can be processed in
00045     32 or 64 bit chunks rather than in bytes.  This define sets the units
00046     in which buffers will be accessed if possible
00047 */
00048 #if !defined( BFR_UNIT )
00049 #  if 1
00050 #    define BFR_UNIT 64
00051 #  elif 0
00052 #    define BFR_UNIT 32
00053 #  else
00054 #    define BFR_UNIT  8
00055 #  endif
00056 #endif
00057 
00058 /*  Use of inlines is preferred but code blocks can also be expanded inline
00059     using 'defines'.  But the latter approach will typically generate a LOT
00060     of code and is not recommended. 
00061 */
00062 #if 1 && !defined( USE_INLINING )
00063 #  define USE_INLINING
00064 #endif
00065 
00066 #include <string.h>
00067 #include <limits.h>
00068 
00069 #if defined( _MSC_VER )
00070 #  if _MSC_VER >= 1400
00071 #    include <stdlib.h>
00072 #    include <intrin.h>
00073 #    pragma intrinsic(memset)
00074 #    pragma intrinsic(memcpy)
00075 #    define rotl32        _rotl
00076 #    define rotr32        _rotr
00077 #    define rotl64        _rotl64
00078 #    define rotr64        _rotl64
00079 #    define bswap_32(x)   _byteswap_ulong(x)
00080 #    define bswap_64(x)   _byteswap_uint64(x)
00081 #  else
00082 #    define rotl32 _lrotl
00083 #    define rotr32 _lrotr
00084 #  endif
00085 #endif
00086 
00087 #if BFR_UNIT == 64
00088 #  define NEED_UINT_64T
00089 #endif
00090 
00091 #include "brg_endian.h"
00092 #include "brg_types.h"
00093 #include "gcm_aes.h"
00094 
00095 #if defined( USE_INLINING )
00096 #  if defined( _MSC_VER )
00097 #    define mh_inline __inline
00098 #  elif defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )
00099 #    define mh_inline static inline
00100 #  else
00101 #    define mh_inline static
00102 #  endif
00103 #endif
00104 
00105 #if defined(__cplusplus)
00106 extern "C" {
00107 #endif
00108 
00109 #define  ui8_ptr(x)  ptr_cast(x,  8)
00110 #define ui16_ptr(x)  ptr_cast(x, 16)
00111 #define ui32_ptr(x)  ptr_cast(x, 32)
00112 #define ui64_ptr(x)  ptr_cast(x, 64)
00113 #define unit_ptr(x)  ptr_cast(x, BFR_UNIT)
00114 
00115 #define BUF_INC     (BFR_UNIT >> 3)
00116 #define BUF_ADRMASK ((BFR_UNIT >> 3) - 1)
00117 
00118 /* function pointers might be used for fast XOR operations */
00119 
00120 typedef void (*xor_function)(void*, const void* q);
00121 
00122 /* left and right rotates on 32 and 64 bit variables */
00123 
00124 #if defined( mh_inline )
00125 
00126 #if !defined( rotl32 )  // NOTE: 0 <= n <= 32 ASSUMED
00127 mh_inline uint_32t rotl32(uint_32t x, int n)
00128 {
00129     return (((x) << n) | ((x) >> (32 - n)));
00130 }
00131 #endif
00132 
00133 #if !defined( rotr32 )  // NOTE: 0 <= n <= 32 ASSUMED
00134 mh_inline uint_32t rotr32(uint_32t x, int n)
00135 {
00136     return (((x) >> n) | ((x) << (32 - n)));
00137 }
00138 #endif
00139 
00140 #if !defined( rotl64 )  // NOTE: 0 <= n <= 64 ASSUMED
00141 mh_inline uint_64t rotl64(uint_64t x, int n)
00142 {
00143     return (((x) << n) | ((x) >> (64 - n)));
00144 }
00145 #endif
00146 
00147 #if !defined( rotr64 )  // NOTE: 0 <= n <= 64 ASSUMED
00148 mh_inline uint_64t rotr64(uint_64t x, int n)
00149 {
00150     return (((x) >> n) | ((x) << (64 - n)));
00151 }
00152 #endif
00153 
00154 /* byte order inversions for 32 and 64 bit variables */
00155 
00156 #if !defined(bswap_32)
00157 mh_inline uint_32t bswap_32(uint_32t x)
00158 {
00159     return ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00));
00160 }
00161 #endif
00162 
00163 #if !defined(bswap_64)
00164 mh_inline uint_64t bswap_64(uint_64t x)
00165 {   
00166     return bswap_32((uint_32t)(x >> 32)) | ((uint_64t)bswap_32((uint_32t)x) << 32);
00167 }
00168 #endif
00169 
00170 mh_inline void bswap32_block(void* d, const void* s, int n)
00171 {
00172     while(n--)
00173         ((uint_32t*)d)[n] = bswap_32(((uint_32t*)s)[n]);
00174 }
00175 
00176 mh_inline void bswap64_block(void* d, const void* s, int n)
00177 {
00178     while(n--)
00179         ((uint_64t*)d)[n] = bswap_64(((uint_64t*)s)[n]);
00180 }
00181 
00182 #else
00183 
00184 #if !defined( rotl32 )  // NOTE: 0 <= n <= 32 ASSUMED
00185 #  define rotl32(x,n)   (((x) << n) | ((x) >> (32 - n)))
00186 #endif
00187 
00188 #if !defined( rotr32 )  // NOTE: 0 <= n <= 32 ASSUMED
00189 #  define rotr32(x,n)   (((x) >> n) | ((x) << (32 - n)))
00190 #endif
00191 
00192 #if !defined( rotl64 )  // NOTE: 0 <= n <= 64 ASSUMED
00193 #  define rotl64(x,n)   (((x) << n) | ((x) >> (64 - n)))
00194 #endif
00195 
00196 #if !defined( rotr64 )  // NOTE: 0 <= n <= 64 ASSUMED
00197 #  define rotr64(x,n)   (((x) >> n) | ((x) << (64 - n)))
00198 #endif
00199 
00200 #if !defined(bswap_32)
00201 #  define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00))
00202 #endif
00203 
00204 #if !defined(bswap_64)
00205 #  define bswap_64(x) (bswap_32((uint_32t)(x >> 32)) | ((uint_64t)bswap_32((uint_32t)x) << 32))
00206 #endif
00207 
00208 #define bswap32_block(d,s,n) \
00209     { int _i = (n); while(_i--) ui32_ptr(d)[_i] = bswap_32(ui32_ptr(s)[_i]); }
00210 
00211 #define bswap64_block(d,s,n) \
00212     { int _i = (n); while(_i--) ui64_ptr(d)[_i] = bswap_64(ui64_ptr(s)[_i]); }
00213 
00214 #endif
00215 
00216 /* support for fast aligned buffer move and XOR operations */
00217 
00218 #if defined( mh_inline )
00219 
00220 mh_inline void move_block(void* p, const void* q)
00221 {
00222     memcpy(p, q, 16);
00223 }
00224 
00225 mh_inline void move_block_aligned( void *p, const void *q)
00226 {
00227 #if BFR_UNIT == 8
00228     move_block(p, q);
00229 #else
00230     unit_ptr(p)[0] = unit_ptr(q)[0]; unit_ptr(p)[1] = unit_ptr(q)[1];
00231 #  if BFR_UNIT == 32
00232     unit_ptr(p)[2] = unit_ptr(q)[2]; unit_ptr(p)[3] = unit_ptr(q)[3];
00233 #  endif
00234 #endif
00235 }
00236 
00237 mh_inline void xor_block(void* p, const void* q)
00238 {
00239     ui8_ptr(p)[ 0] ^= ui8_ptr(q)[ 0]; ui8_ptr(p)[ 1] ^= ui8_ptr(q)[ 1];
00240     ui8_ptr(p)[ 2] ^= ui8_ptr(q)[ 2]; ui8_ptr(p)[ 3] ^= ui8_ptr(q)[ 3];
00241     ui8_ptr(p)[ 4] ^= ui8_ptr(q)[ 4]; ui8_ptr(p)[ 5] ^= ui8_ptr(q)[ 5];
00242     ui8_ptr(p)[ 6] ^= ui8_ptr(q)[ 6]; ui8_ptr(p)[ 7] ^= ui8_ptr(q)[ 7];
00243     ui8_ptr(p)[ 8] ^= ui8_ptr(q)[ 8]; ui8_ptr(p)[ 9] ^= ui8_ptr(q)[ 9];
00244     ui8_ptr(p)[10] ^= ui8_ptr(q)[10]; ui8_ptr(p)[11] ^= ui8_ptr(q)[11];
00245     ui8_ptr(p)[12] ^= ui8_ptr(q)[12]; ui8_ptr(p)[13] ^= ui8_ptr(q)[13];
00246     ui8_ptr(p)[14] ^= ui8_ptr(q)[14]; ui8_ptr(p)[15] ^= ui8_ptr(q)[15];
00247 }
00248 
00249 mh_inline void xor_block_aligned( void *p, const void *q)
00250 {
00251 #if BFR_UNIT == 8
00252     xor_block(p, q);
00253 #else
00254     unit_ptr(p)[0] ^= unit_ptr(q)[0]; unit_ptr(p)[1] ^= unit_ptr(q)[1];
00255 #  if BFR_UNIT == 32
00256     unit_ptr(p)[2] ^= unit_ptr(q)[2]; unit_ptr(p)[3] ^= unit_ptr(q)[3];
00257 #  endif
00258 #endif
00259 }
00260 
00261 #else
00262 
00263 #define move_block(p,q) memcpy((p), (q), 16)
00264 
00265 #if BFR_UNIT == 64
00266 #  define move_block_aligned(p,q) \
00267    ui64_ptr(p)[0] = ui64_ptr(q)[0], ui64_ptr(p)[1] = ui64_ptr(q)[1]
00268 #elif BFR_UNIT == 32
00269 #  define move_block_aligned(p,q) \
00270    ui32_ptr(p)[0] = ui32_ptr(q)[0], ui32_ptr(p)[1] = ui32_ptr(q)[1], \
00271    ui32_ptr(p)[2] = ui32_ptr(q)[2], ui32_ptr(p)[3] = ui32_ptr(q)[3]
00272 #else
00273 #  define move_block_aligned(p,q) move_block(p,q)
00274 #endif
00275 
00276 #define xor_block(p,q) \
00277     ui8_ptr(p)[ 0] ^= ui8_ptr(q)[ 0], ui8_ptr(p)[ 1] ^= ui8_ptr(q)[ 1], \
00278     ui8_ptr(p)[ 2] ^= ui8_ptr(q)[ 2], ui8_ptr(p)[ 3] ^= ui8_ptr(q)[ 3], \
00279     ui8_ptr(p)[ 4] ^= ui8_ptr(q)[ 4], ui8_ptr(p)[ 5] ^= ui8_ptr(q)[ 5], \
00280     ui8_ptr(p)[ 6] ^= ui8_ptr(q)[ 6], ui8_ptr(p)[ 7] ^= ui8_ptr(q)[ 7], \
00281     ui8_ptr(p)[ 8] ^= ui8_ptr(q)[ 8], ui8_ptr(p)[ 9] ^= ui8_ptr(q)[ 9], \
00282     ui8_ptr(p)[10] ^= ui8_ptr(q)[10], ui8_ptr(p)[11] ^= ui8_ptr(q)[11], \
00283     ui8_ptr(p)[12] ^= ui8_ptr(q)[12], ui8_ptr(p)[13] ^= ui8_ptr(q)[13], \
00284     ui8_ptr(p)[14] ^= ui8_ptr(q)[14], ui8_ptr(p)[15] ^= ui8_ptr(q)[15]
00285 
00286 #if BFR_UNIT == 64
00287 #  define xor_block_aligned(p,q) \
00288    ui64_ptr(p)[0] ^= ui64_ptr(q)[0], ui64_ptr(p)[1] ^= ui64_ptr(q)[1]
00289 #elif BFR_UNIT == 32
00290 #  define xor_block_aligned(p,q) \
00291    ui32_ptr(p)[0] ^= ui32_ptr(q)[0], ui32_ptr(p)[1] ^= ui32_ptr(q)[1], \
00292    ui32_ptr(p)[2] ^= ui32_ptr(q)[2], ui32_ptr(p)[3] ^= ui32_ptr(q)[3]
00293 #else
00294 #  define xor_block_aligned(p,q)  xor_block(p,q)
00295 #endif
00296 
00297 #endif
00298 
00299 /* platform byte order to big or little endian order for 32 and 64 bit variables */
00300 
00301 #if PLATFORM_BYTE_ORDER == IS_BIG_ENDIAN
00302 #  define uint_32t_to_le(x) (x) = bswap_32((x))
00303 #  define uint_64t_to_le(x) (x) = bswap_64((x))
00304 #  define uint_32t_to_be(x)
00305 #  define uint_64t_to_be(x)
00306 #else
00307 #  define uint_32t_to_le(x)
00308 #  define uint_64t_to_le(x)
00309 #  define uint_32t_to_be(x) (x) = bswap_32((x))
00310 #  define uint_64t_to_be(x) (x) = bswap_64((x))
00311 #endif
00312 
00313 #if defined(__cplusplus)
00314 }
00315 #endif
00316 
00317 #endif