security/nss/lib/freebl/rijndael_tables.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include "stdio.h"
     6 #include "prtypes.h"
     7 #include "blapi.h"
     9 /*
    10  * what follows is code thrown together to generate the myriad of tables
    11  * used by Rijndael, the AES cipher.
    12  */
    15 #define WORD_LE(b0, b1, b2, b3) \
    16     (((b3) << 24) | ((b2) << 16) | ((b1) << 8) | b0)
    18 #define WORD_BE(b0, b1, b2, b3) \
    19     (((b0) << 24) | ((b1) << 16) | ((b2) << 8) | b3)
    21 static const PRUint8 __S[256] = 
    22 {
    23  99, 124, 119, 123, 242, 107, 111, 197,  48,   1, 103,  43, 254, 215, 171, 118, 
    24 202, 130, 201, 125, 250,  89,  71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 
    25 183, 253, 147,  38,  54,  63, 247, 204,  52, 165, 229, 241, 113, 216,  49,  21, 
    26   4, 199,  35, 195,  24, 150,   5, 154,   7,  18, 128, 226, 235,  39, 178, 117, 
    27   9, 131,  44,  26,  27, 110,  90, 160,  82,  59, 214, 179,  41, 227,  47, 132, 
    28  83, 209,   0, 237,  32, 252, 177,  91, 106, 203, 190,  57,  74,  76,  88, 207, 
    29 208, 239, 170, 251,  67,  77,  51, 133,  69, 249,   2, 127,  80,  60, 159, 168, 
    30  81, 163,  64, 143, 146, 157,  56, 245, 188, 182, 218,  33,  16, 255, 243, 210, 
    31 205,  12,  19, 236,  95, 151,  68,  23, 196, 167, 126,  61, 100,  93,  25, 115, 
    32  96, 129,  79, 220,  34,  42, 144, 136,  70, 238, 184,  20, 222,  94,  11, 219, 
    33 224,  50,  58,  10,  73,   6,  36,  92, 194, 211, 172,  98, 145, 149, 228, 121, 
    34 231, 200,  55, 109, 141, 213,  78, 169, 108,  86, 244, 234, 101, 122, 174,   8, 
    35 186, 120,  37,  46,  28, 166, 180, 198, 232, 221, 116,  31,  75, 189, 139, 138, 
    36 112,  62, 181, 102,  72,   3, 246,  14,  97,  53,  87, 185, 134, 193,  29, 158, 
    37 225, 248, 152,  17, 105, 217, 142, 148, 155,  30, 135, 233, 206,  85,  40, 223, 
    38 140, 161, 137,  13, 191, 230,  66, 104,  65, 153,  45,  15, 176,  84, 187,  22, 
    39 };
    41 static const PRUint8 __SInv[256] = 
    42 {
    43  82,   9, 106, 213,  48,  54, 165,  56, 191,  64, 163, 158, 129, 243, 215, 251, 
    44 124, 227,  57, 130, 155,  47, 255, 135,  52, 142,  67,  68, 196, 222, 233, 203, 
    45  84, 123, 148,  50, 166, 194,  35,  61, 238,  76, 149,  11,  66, 250, 195,  78, 
    46   8,  46, 161, 102,  40, 217,  36, 178, 118,  91, 162,  73, 109, 139, 209,  37, 
    47 114, 248, 246, 100, 134, 104, 152,  22, 212, 164,  92, 204,  93, 101, 182, 146, 
    48 108, 112,  72,  80, 253, 237, 185, 218,  94,  21,  70,  87, 167, 141, 157, 132, 
    49 144, 216, 171,   0, 140, 188, 211,  10, 247, 228,  88,   5, 184, 179,  69,   6, 
    50 208,  44,  30, 143, 202,  63,  15,   2, 193, 175, 189,   3,   1,  19, 138, 107, 
    51  58, 145,  17,  65,  79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115, 
    52 150, 172, 116,  34, 231, 173,  53, 133, 226, 249,  55, 232,  28, 117, 223, 110, 
    53  71, 241,  26, 113,  29,  41, 197, 137, 111, 183,  98,  14, 170,  24, 190,  27, 
    54 252,  86,  62,  75, 198, 210, 121,  32, 154, 219, 192, 254, 120, 205,  90, 244, 
    55  31, 221, 168,  51, 136,   7, 199,  49, 177,  18,  16,  89,  39, 128, 236,  95, 
    56  96,  81, 127, 169,  25, 181,  74,  13,  45, 229, 122, 159, 147, 201, 156, 239, 
    57 160, 224,  59,  77, 174,  42, 245, 176, 200, 235, 187,  60, 131,  83, 153,  97, 
    58  23,  43,   4, 126, 186, 119, 214,  38, 225, 105,  20,  99,  85,  33,  12, 125
    59 };
    61 /* GF_MULTIPLY
    62  *
    63  * multiply two bytes represented in GF(2**8), mod (x**4 + 1)
    64  */
    65 PRUint8 gf_multiply(PRUint8 a, PRUint8 b)
    66 {
    67     PRUint8 res = 0;
    68     while (b > 0) {
    69 	res = (b & 0x01) ? res ^ a : res;
    70 	a = (a & 0x80) ? ((a << 1) ^ 0x1b) : (a << 1);
    71 	b >>= 1;
    72     }
    73     return res;
    74 }
    76 void
    77 make_T_Table(char *table, const PRUint8 Sx[256], FILE *file,
    78              unsigned char m0, unsigned char m1, 
    79              unsigned char m2, unsigned char m3)
    80 {
    81     PRUint32 Ti;
    82     int i;
    83     fprintf(file, "#ifdef IS_LITTLE_ENDIAN\n");
    84     fprintf(file, "static const PRUint32 _T%s[256] = \n{\n", table);
    85     for (i=0; i<256; i++) {
    86 	Ti = WORD_LE( gf_multiply(Sx[i], m0),
    87 	              gf_multiply(Sx[i], m1),
    88 	              gf_multiply(Sx[i], m2),
    89 	              gf_multiply(Sx[i], m3) );
    90 	if (Ti == 0)
    91 	    fprintf(file, "0x00000000%c%c", (i==255)?' ':',',
    92 	                                    (i%6==5)?'\n':' ');
    93 	else
    94 	    fprintf(file, "%#.8x%c%c", Ti, (i==255)?' ':',',
    95 	                                   (i%6==5)?'\n':' ');
    96     }
    97     fprintf(file, "\n};\n");
    98     fprintf(file, "#else\n");
    99     fprintf(file, "static const PRUint32 _T%s[256] = \n{\n", table);
   100     for (i=0; i<256; i++) {
   101 	Ti = WORD_BE( gf_multiply(Sx[i], m0),
   102 	              gf_multiply(Sx[i], m1),
   103 	              gf_multiply(Sx[i], m2),
   104 	              gf_multiply(Sx[i], m3) );
   105 	if (Ti == 0)
   106 	    fprintf(file, "0x00000000%c%c", (i==255)?' ':',',
   107 	                                    (i%6==5)?'\n':' ');
   108 	else
   109 	    fprintf(file, "%#.8x%c%c", Ti, (i==255)?' ':',',
   110 	                                   (i%6==5)?'\n':' ');
   111     }
   112     fprintf(file, "\n};\n");
   113     fprintf(file, "#endif\n\n");
   114 }
   116 void make_InvMixCol_Table(int num, FILE *file, PRUint8 m0, PRUint8 m1, PRUint8 m2, PRUint8 m3)
   117 {
   118     PRUint16 i;
   119     PRUint8 b0, b1, b2, b3;
   120     fprintf(file, "#ifdef IS_LITTLE_ENDIAN\n");
   121     fprintf(file, "static const PRUint32 _IMXC%d[256] = \n{\n", num);
   122     for (i=0; i<256; i++) {
   123 	b0 = gf_multiply(i, m0);
   124 	b1 = gf_multiply(i, m1);
   125 	b2 = gf_multiply(i, m2);
   126 	b3 = gf_multiply(i, m3);
   127 	fprintf(file, "0x%.2x%.2x%.2x%.2x%c%c", b3, b2, b1, b0, (i==255)?' ':',', (i%6==5)?'\n':' ');
   128     }
   129     fprintf(file, "\n};\n");
   130     fprintf(file, "#else\n");
   131     fprintf(file, "static const PRUint32 _IMXC%d[256] = \n{\n", num);
   132     for (i=0; i<256; i++) {
   133 	b0 = gf_multiply(i, m0);
   134 	b1 = gf_multiply(i, m1);
   135 	b2 = gf_multiply(i, m2);
   136 	b3 = gf_multiply(i, m3);
   137 	fprintf(file, "0x%.2x%.2x%.2x%.2x%c%c", b0, b1, b2, b3, (i==255)?' ':',', (i%6==5)?'\n':' ');
   138     }
   139     fprintf(file, "\n};\n");
   140     fprintf(file, "#endif\n\n");
   141 }
   143 int main()
   144 {
   145     int i, j;
   146     PRUint8 cur, last;
   147     PRUint32 tmp;
   148     FILE *optfile;
   149     optfile = fopen("rijndael32.tab", "w");
   150     /* output S, if there are no T tables */
   151     fprintf(optfile, "#ifndef RIJNDAEL_INCLUDE_TABLES\n");
   152     fprintf(optfile, "static const PRUint8 _S[256] = \n{\n");
   153     for (i=0; i<256; i++) {
   154 	fprintf(optfile, "%3d%c%c", __S[i],(i==255)?' ':',', 
   155 	                            (i%16==15)?'\n':' ');
   156     }
   157     fprintf(optfile, "};\n#endif /* not RIJNDAEL_INCLUDE_TABLES */\n\n");
   158     /* output S**-1 */
   159     fprintf(optfile, "static const PRUint8 _SInv[256] = \n{\n");
   160     for (i=0; i<256; i++) {
   161 	fprintf(optfile, "%3d%c%c", __SInv[i],(i==255)?' ':',', 
   162 	                            (i%16==15)?'\n':' ');
   163     }
   164     fprintf(optfile, "};\n\n");
   165     fprintf(optfile, "#ifdef RIJNDAEL_INCLUDE_TABLES\n");
   166     /* The 32-bit word tables for optimized implementation */
   167     /* T0 = [ S[a] * 02, S[a], S[a], S[a] * 03 ] */
   168     make_T_Table("0", __S, optfile, 0x02, 0x01, 0x01, 0x03);
   169     /* T1 = [ S[a] * 03, S[a] * 02, S[a], S[a] ] */
   170     make_T_Table("1", __S, optfile, 0x03, 0x02, 0x01, 0x01);
   171     /* T2 = [ S[a], S[a] * 03, S[a] * 02, S[a] ] */
   172     make_T_Table("2", __S, optfile, 0x01, 0x03, 0x02, 0x01);
   173     /* T3 = [ S[a], S[a], S[a] * 03, S[a] * 02 ] */
   174     make_T_Table("3", __S, optfile, 0x01, 0x01, 0x03, 0x02);
   175     /* TInv0 = [ Si[a] * 0E, Si[a] * 09, Si[a] * 0D, Si[a] * 0B ] */
   176     make_T_Table("Inv0", __SInv, optfile, 0x0e, 0x09, 0x0d, 0x0b);
   177     /* TInv1 = [ Si[a] * 0B, Si[a] * 0E, Si[a] * 09, Si[a] * 0D ] */
   178     make_T_Table("Inv1", __SInv, optfile, 0x0b, 0x0e, 0x09, 0x0d);
   179     /* TInv2 = [ Si[a] * 0D, Si[a] * 0B, Si[a] * 0E, Si[a] * 09 ] */
   180     make_T_Table("Inv2", __SInv, optfile, 0x0d, 0x0b, 0x0e, 0x09);
   181     /* TInv3 = [ Si[a] * 09, Si[a] * 0D, Si[a] * 0B, Si[a] * 0E ] */
   182     make_T_Table("Inv3", __SInv, optfile, 0x09, 0x0d, 0x0b, 0x0e);
   183     /* byte multiply tables for inverse key expansion (mimics InvMixColumn) */
   184     make_InvMixCol_Table(0, optfile, 0x0e, 0x09, 0x0d, 0x0b);
   185     make_InvMixCol_Table(1, optfile, 0x0b, 0x0E, 0x09, 0x0d);
   186     make_InvMixCol_Table(2, optfile, 0x0d, 0x0b, 0x0e, 0x09);
   187     make_InvMixCol_Table(3, optfile, 0x09, 0x0d, 0x0b, 0x0e);
   188     fprintf(optfile, "#endif /* RIJNDAEL_INCLUDE_TABLES */\n\n");
   189     /* round constants for key expansion */
   190     fprintf(optfile, "#ifdef IS_LITTLE_ENDIAN\n");
   191     fprintf(optfile, "static const PRUint32 Rcon[30] = {\n");
   192     cur = 0x01;
   193     for (i=0; i<30; i++) {
   194 	fprintf(optfile, "%#.8x%c%c", WORD_LE(cur, 0, 0, 0), 
   195 	                                (i==29)?' ':',', (i%6==5)?'\n':' ');
   196 	last = cur;
   197 	cur = gf_multiply(last, 0x02);
   198     }
   199     fprintf(optfile, "};\n");
   200     fprintf(optfile, "#else\n");
   201     fprintf(optfile, "static const PRUint32 Rcon[30] = {\n");
   202     cur = 0x01;
   203     for (i=0; i<30; i++) {
   204 	fprintf(optfile, "%#.8x%c%c", WORD_BE(cur, 0, 0, 0), 
   205 	                                (i==29)?' ':',', (i%6==5)?'\n':' ');
   206 	last = cur;
   207 	cur = gf_multiply(last, 0x02);
   208     }
   209     fprintf(optfile, "};\n");
   210     fprintf(optfile, "#endif\n\n");
   211     fclose(optfile);
   212     return 0;
   213 }

mercurial