IBR-DTNSuite  0.8
ibrcommon/ibrcommon/ssl/gcm/gf128mul.cc
Go to the documentation of this file.
00001 
00002 /*
00003  ---------------------------------------------------------------------------
00004  Copyright (c) 1998-2006, Brian Gladman, Worcester, UK. All rights reserved.
00005 
00006  LICENSE TERMS
00007 
00008  The free distribution and use of this software in both source and binary
00009  form is allowed (with or without changes) provided that:
00010 
00011    1. distributions of this source code include the above copyright
00012       notice, this list of conditions and the following disclaimer;
00013 
00014    2. distributions in binary form include the above copyright
00015       notice, this list of conditions and the following disclaimer
00016       in the documentation and/or other associated materials;
00017 
00018    3. the copyright holder's name is not used to endorse products
00019       built using this software without specific written permission.
00020 
00021  ALTERNATIVELY, provided that this notice is retained in full, this product
00022  may be distributed under the terms of the GNU General Public License (GPL),
00023  in which case the provisions of the GPL apply INSTEAD OF those given above.
00024 
00025  DISCLAIMER
00026 
00027  This software is provided 'as is' with no explicit or implied warranties
00028  in respect of its properties, including, but not limited to, correctness
00029  and/or fitness for purpose.
00030  ---------------------------------------------------------------------------
00031  Issue 31/01/2006
00032 
00033  This file provides fast multiplication in GF(128) as required by several
00034  cryptographic authentication modes
00035 */
00036 
00037 //#ifdef HAVE_CONFIG_H
00038 //#  include <dtn-config.h>
00039 //#endif
00040 #define BSP_ENABLED true
00041 
00042 #ifdef BSP_ENABLED
00043 
00044 #include "brg_types.h"
00045 #include "brg_endian.h"
00046 #include "gf128mul.h"
00047 
00048 #define gf_dat(q) {\
00049     q(0x00), q(0x01), q(0x02), q(0x03), q(0x04), q(0x05), q(0x06), q(0x07),\
00050     q(0x08), q(0x09), q(0x0a), q(0x0b), q(0x0c), q(0x0d), q(0x0e), q(0x0f),\
00051     q(0x10), q(0x11), q(0x12), q(0x13), q(0x14), q(0x15), q(0x16), q(0x17),\
00052     q(0x18), q(0x19), q(0x1a), q(0x1b), q(0x1c), q(0x1d), q(0x1e), q(0x1f),\
00053     q(0x20), q(0x21), q(0x22), q(0x23), q(0x24), q(0x25), q(0x26), q(0x27),\
00054     q(0x28), q(0x29), q(0x2a), q(0x2b), q(0x2c), q(0x2d), q(0x2e), q(0x2f),\
00055     q(0x30), q(0x31), q(0x32), q(0x33), q(0x34), q(0x35), q(0x36), q(0x37),\
00056     q(0x38), q(0x39), q(0x3a), q(0x3b), q(0x3c), q(0x3d), q(0x3e), q(0x3f),\
00057     q(0x40), q(0x41), q(0x42), q(0x43), q(0x44), q(0x45), q(0x46), q(0x47),\
00058     q(0x48), q(0x49), q(0x4a), q(0x4b), q(0x4c), q(0x4d), q(0x4e), q(0x4f),\
00059     q(0x50), q(0x51), q(0x52), q(0x53), q(0x54), q(0x55), q(0x56), q(0x57),\
00060     q(0x58), q(0x59), q(0x5a), q(0x5b), q(0x5c), q(0x5d), q(0x5e), q(0x5f),\
00061     q(0x60), q(0x61), q(0x62), q(0x63), q(0x64), q(0x65), q(0x66), q(0x67),\
00062     q(0x68), q(0x69), q(0x6a), q(0x6b), q(0x6c), q(0x6d), q(0x6e), q(0x6f),\
00063     q(0x70), q(0x71), q(0x72), q(0x73), q(0x74), q(0x75), q(0x76), q(0x77),\
00064     q(0x78), q(0x79), q(0x7a), q(0x7b), q(0x7c), q(0x7d), q(0x7e), q(0x7f),\
00065     q(0x80), q(0x81), q(0x82), q(0x83), q(0x84), q(0x85), q(0x86), q(0x87),\
00066     q(0x88), q(0x89), q(0x8a), q(0x8b), q(0x8c), q(0x8d), q(0x8e), q(0x8f),\
00067     q(0x90), q(0x91), q(0x92), q(0x93), q(0x94), q(0x95), q(0x96), q(0x97),\
00068     q(0x98), q(0x99), q(0x9a), q(0x9b), q(0x9c), q(0x9d), q(0x9e), q(0x9f),\
00069     q(0xa0), q(0xa1), q(0xa2), q(0xa3), q(0xa4), q(0xa5), q(0xa6), q(0xa7),\
00070     q(0xa8), q(0xa9), q(0xaa), q(0xab), q(0xac), q(0xad), q(0xae), q(0xaf),\
00071     q(0xb0), q(0xb1), q(0xb2), q(0xb3), q(0xb4), q(0xb5), q(0xb6), q(0xb7),\
00072     q(0xb8), q(0xb9), q(0xba), q(0xbb), q(0xbc), q(0xbd), q(0xbe), q(0xbf),\
00073     q(0xc0), q(0xc1), q(0xc2), q(0xc3), q(0xc4), q(0xc5), q(0xc6), q(0xc7),\
00074     q(0xc8), q(0xc9), q(0xca), q(0xcb), q(0xcc), q(0xcd), q(0xce), q(0xcf),\
00075     q(0xd0), q(0xd1), q(0xd2), q(0xd3), q(0xd4), q(0xd5), q(0xd6), q(0xd7),\
00076     q(0xd8), q(0xd9), q(0xda), q(0xdb), q(0xdc), q(0xdd), q(0xde), q(0xdf),\
00077     q(0xe0), q(0xe1), q(0xe2), q(0xe3), q(0xe4), q(0xe5), q(0xe6), q(0xe7),\
00078     q(0xe8), q(0xe9), q(0xea), q(0xeb), q(0xec), q(0xed), q(0xee), q(0xef),\
00079     q(0xf0), q(0xf1), q(0xf2), q(0xf3), q(0xf4), q(0xf5), q(0xf6), q(0xf7),\
00080     q(0xf8), q(0xf9), q(0xfa), q(0xfb), q(0xfc), q(0xfd), q(0xfe), q(0xff) }
00081 
00082 
00083 /*  Given the value i in 0..255 as the byte overflow when a field element
00084     in GHASH is multipled by x^8, this function will return the values that
00085     are generated in the lo 16-bit word of the field value by applying the
00086     modular polynomial. The values lo_byte and hi_byte are returned via the
00087     macro xp_fun(lo_byte, hi_byte) so that the values can be assembled into
00088     memory as required by a suitable definition of this macro operating on
00089     the table above
00090 */
00091 
00092 #if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
00093 #  define xx(p,q)   0x##q##p    /* assemble in little endian order */
00094 #else
00095 #  define xx(p,q)   0x##p##q    /* assemble in big endian order    */
00096 #endif
00097 
00098 #define xda(i) (                                              \
00099     (i & 0x80 ? xx(e1,00) : 0) ^ (i & 0x40 ? xx(70,80) : 0) ^ \
00100     (i & 0x20 ? xx(38,40) : 0) ^ (i & 0x10 ? xx(1c,20) : 0) ^ \
00101     (i & 0x08 ? xx(0e,10) : 0) ^ (i & 0x04 ? xx(07,08) : 0) ^ \
00102     (i & 0x02 ? xx(03,84) : 0) ^ (i & 0x01 ? xx(01,c2) : 0) )
00103 
00104 const unsigned short gf_tab[256] = gf_dat(xda);
00105 
00106 void gf_mul(void *a, const void* b)
00107 {   uint_32t r[GF_BYTE_LEN >> 2], p[8][GF_BYTE_LEN >> 2];
00108     int i;
00109 
00110     move_block_aligned(p[0], b);
00111     for(i = 0; i < 7; ++i)
00112         mul_x(p[i + 1], p[i]);
00113 
00114     memset(r, 0, GF_BYTE_LEN);
00115     for(i = 0; i < 16; ++i)
00116     {   unsigned char ch = ((unsigned char*)a)[15 - i];
00117         if(i) mul_x8(r);
00118 
00119         if(ch & 0x80)
00120             xor_block_aligned(r, p[0]);
00121         if(ch & 0x40)
00122             xor_block_aligned(r, p[1]);
00123         if(ch & 0x20)
00124             xor_block_aligned(r, p[2]);
00125         if(ch & 0x10)
00126             xor_block_aligned(r, p[3]);
00127         if(ch & 0x08)
00128             xor_block_aligned(r, p[4]);
00129         if(ch & 0x04)
00130             xor_block_aligned(r, p[5]);
00131         if(ch & 0x02)
00132             xor_block_aligned(r, p[6]);
00133         if(ch & 0x01)
00134             xor_block_aligned(r, p[7]);
00135     }
00136     move_block_aligned(a, r);
00137 }
00138 
00139 #if defined( TABLES_64K )
00140 
00141 void init_64k_table(unsigned char g[], void *t)
00142 {   int i, j, k;
00143 
00144     memset(t, 0, 16 * 256 * 16);
00145     for(i = 0; i < GF_BYTE_LEN; ++i)
00146     {
00147         if(!i)
00148         {
00149             memcpy(tab64k(t)[0][128], g, GF_BYTE_LEN);
00150             for(j = 64; j > 0; j >>= 1)
00151                 mul_x(tab64k(t)[0][j], tab64k(t)[0][j + j]);
00152         }
00153         else
00154             for(j = 128; j > 0; j >>= 1)
00155             {
00156                 memcpy(tab64k(t)[i][j], tab64k(t)[i - 1][j], GF_BYTE_LEN);
00157                 mul_x8(tab64k(t)[i][j]);
00158             }
00159 
00160         for(j = 2; j < 256; j += j)
00161             for(k = 1; k < j; ++k)
00162             {
00163                 tab64k(t)[i][j + k][0] = tab64k(t)[i][j][0] ^ tab64k(t)[i][k][0];
00164                 tab64k(t)[i][j + k][1] = tab64k(t)[i][j][1] ^ tab64k(t)[i][k][1];
00165                 tab64k(t)[i][j + k][2] = tab64k(t)[i][j][2] ^ tab64k(t)[i][k][2];
00166                 tab64k(t)[i][j + k][3] = tab64k(t)[i][j][3] ^ tab64k(t)[i][k][3];
00167             }
00168     }
00169 }
00170 
00171 #endif
00172 
00173 #if defined( TABLES_8K )
00174 
00175 void init_8k_table(unsigned char g[], void *t)
00176 {   int i, j, k;
00177 
00178     memset(tab8k(t), 0, 32 * 16 * 16);
00179     for(i = 0; i < 2 * GF_BYTE_LEN; ++i)
00180     {
00181         if(i == 0)
00182         {
00183             memcpy(tab8k(t)[1][8], g, GF_BYTE_LEN);
00184             for(j = 4; j > 0; j >>= 1)
00185                 mul_x(tab8k(t)[1][j], tab8k(t)[1][j + j]);
00186 
00187             mul_x(tab8k(t)[0][8], tab8k(t)[1][1]);
00188 
00189             for(j = 4; j > 0; j >>= 1)
00190                 mul_x(tab8k(t)[0][j], tab8k(t)[0][j + j]);
00191         }
00192         else if(i > 1)
00193             for(j = 8; j > 0; j >>= 1)
00194             {
00195                 memcpy(tab8k(t)[i][j], tab8k(t)[i - 2][j], GF_BYTE_LEN);
00196                 mul_x8(tab8k(t)[i][j]);
00197             }
00198 
00199         for(j = 2; j < 16; j += j)
00200             for(k = 1; k < j; ++k)
00201             {
00202                 tab8k(t)[i][j + k][0] = tab8k(t)[i][j][0] ^ tab8k(t)[i][k][0];
00203                 tab8k(t)[i][j + k][1] = tab8k(t)[i][j][1] ^ tab8k(t)[i][k][1];
00204                 tab8k(t)[i][j + k][2] = tab8k(t)[i][j][2] ^ tab8k(t)[i][k][2];
00205                 tab8k(t)[i][j + k][3] = tab8k(t)[i][j][3] ^ tab8k(t)[i][k][3];
00206             }
00207     }
00208 }
00209 
00210 #endif
00211 
00212 #if defined( TABLES_4K )
00213 
00214 void init_4k_table(unsigned char g[], void *t)
00215 {   int j, k;
00216 
00217     memset(tab4k(t), 0, 256 * 16);
00218     memcpy(tab4k(t)[128], g, GF_BYTE_LEN);
00219     for(j = 64; j > 0; j >>= 1)
00220     {
00221         mul_x(tab4k(t)[j], tab4k(t)[j + j]);
00222     }
00223 
00224     for(j = 2; j < 256; j += j)
00225         for(k = 1; k < j; ++k)
00226         {
00227             tab4k(t)[j + k][0] = tab4k(t)[j][0] ^ tab4k(t)[k][0];
00228             tab4k(t)[j + k][1] = tab4k(t)[j][1] ^ tab4k(t)[k][1];
00229             tab4k(t)[j + k][2] = tab4k(t)[j][2] ^ tab4k(t)[k][2];
00230             tab4k(t)[j + k][3] = tab4k(t)[j][3] ^ tab4k(t)[k][3];
00231         }
00232 }
00233 
00234 #endif
00235 
00236 #if defined( TABLES_256 )
00237 
00238 void init_256_table(unsigned char g[], void *t)
00239 {   int j, k;
00240 
00241     memset(tab256(t), 0, 16 * 16);
00242     memcpy(tab256(t)[8], g, GF_BYTE_LEN);
00243     for(j = 4; j > 0; j >>= 1)
00244     {
00245         mul_x(tab256(t)[j], tab256(t)[j + j]);
00246     }
00247 
00248     for(j = 2; j < 16; j += j)
00249         for(k = 1; k < j; ++k)
00250         {
00251             tab256(t)[j + k][0] = tab256(t)[j][0] ^ tab256(t)[k][0];
00252             tab256(t)[j + k][1] = tab256(t)[j][1] ^ tab256(t)[k][1];
00253             tab256(t)[j + k][2] = tab256(t)[j][2] ^ tab256(t)[k][2];
00254             tab256(t)[j + k][3] = tab256(t)[j][3] ^ tab256(t)[k][3];
00255         }
00256 }
00257 
00258 #endif
00259 
00260 #endif /* BSP_ENABLED */