Back to index

lightning-sunbird  0.9+nobinonly
rijndael_tables.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 /* $Id: rijndael_tables.c,v 1.4 2004/04/27 23:04:36 gerv%gerv.net Exp $ */
00037 
00038 #include "stdio.h"
00039 #include "prtypes.h"
00040 #include "blapi.h"
00041 
00042 /*
00043  * what follows is code thrown together to generate the myriad of tables
00044  * used by Rijndael, the AES cipher.
00045  */
00046 
00047 
00048 #define WORD_LE(b0, b1, b2, b3) \
00049     (((b3) << 24) | ((b2) << 16) | ((b1) << 8) | b0)
00050 
00051 #define WORD_BE(b0, b1, b2, b3) \
00052     (((b0) << 24) | ((b1) << 16) | ((b2) << 8) | b3)
00053 
00054 static const PRUint8 __S[256] = 
00055 {
00056  99, 124, 119, 123, 242, 107, 111, 197,  48,   1, 103,  43, 254, 215, 171, 118, 
00057 202, 130, 201, 125, 250,  89,  71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 
00058 183, 253, 147,  38,  54,  63, 247, 204,  52, 165, 229, 241, 113, 216,  49,  21, 
00059   4, 199,  35, 195,  24, 150,   5, 154,   7,  18, 128, 226, 235,  39, 178, 117, 
00060   9, 131,  44,  26,  27, 110,  90, 160,  82,  59, 214, 179,  41, 227,  47, 132, 
00061  83, 209,   0, 237,  32, 252, 177,  91, 106, 203, 190,  57,  74,  76,  88, 207, 
00062 208, 239, 170, 251,  67,  77,  51, 133,  69, 249,   2, 127,  80,  60, 159, 168, 
00063  81, 163,  64, 143, 146, 157,  56, 245, 188, 182, 218,  33,  16, 255, 243, 210, 
00064 205,  12,  19, 236,  95, 151,  68,  23, 196, 167, 126,  61, 100,  93,  25, 115, 
00065  96, 129,  79, 220,  34,  42, 144, 136,  70, 238, 184,  20, 222,  94,  11, 219, 
00066 224,  50,  58,  10,  73,   6,  36,  92, 194, 211, 172,  98, 145, 149, 228, 121, 
00067 231, 200,  55, 109, 141, 213,  78, 169, 108,  86, 244, 234, 101, 122, 174,   8, 
00068 186, 120,  37,  46,  28, 166, 180, 198, 232, 221, 116,  31,  75, 189, 139, 138, 
00069 112,  62, 181, 102,  72,   3, 246,  14,  97,  53,  87, 185, 134, 193,  29, 158, 
00070 225, 248, 152,  17, 105, 217, 142, 148, 155,  30, 135, 233, 206,  85,  40, 223, 
00071 140, 161, 137,  13, 191, 230,  66, 104,  65, 153,  45,  15, 176,  84, 187,  22, 
00072 };
00073 
00074 static const PRUint8 __SInv[256] = 
00075 {
00076  82,   9, 106, 213,  48,  54, 165,  56, 191,  64, 163, 158, 129, 243, 215, 251, 
00077 124, 227,  57, 130, 155,  47, 255, 135,  52, 142,  67,  68, 196, 222, 233, 203, 
00078  84, 123, 148,  50, 166, 194,  35,  61, 238,  76, 149,  11,  66, 250, 195,  78, 
00079   8,  46, 161, 102,  40, 217,  36, 178, 118,  91, 162,  73, 109, 139, 209,  37, 
00080 114, 248, 246, 100, 134, 104, 152,  22, 212, 164,  92, 204,  93, 101, 182, 146, 
00081 108, 112,  72,  80, 253, 237, 185, 218,  94,  21,  70,  87, 167, 141, 157, 132, 
00082 144, 216, 171,   0, 140, 188, 211,  10, 247, 228,  88,   5, 184, 179,  69,   6, 
00083 208,  44,  30, 143, 202,  63,  15,   2, 193, 175, 189,   3,   1,  19, 138, 107, 
00084  58, 145,  17,  65,  79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115, 
00085 150, 172, 116,  34, 231, 173,  53, 133, 226, 249,  55, 232,  28, 117, 223, 110, 
00086  71, 241,  26, 113,  29,  41, 197, 137, 111, 183,  98,  14, 170,  24, 190,  27, 
00087 252,  86,  62,  75, 198, 210, 121,  32, 154, 219, 192, 254, 120, 205,  90, 244, 
00088  31, 221, 168,  51, 136,   7, 199,  49, 177,  18,  16,  89,  39, 128, 236,  95, 
00089  96,  81, 127, 169,  25, 181,  74,  13,  45, 229, 122, 159, 147, 201, 156, 239, 
00090 160, 224,  59,  77, 174,  42, 245, 176, 200, 235, 187,  60, 131,  83, 153,  97, 
00091  23,  43,   4, 126, 186, 119, 214,  38, 225, 105,  20,  99,  85,  33,  12, 125
00092 };
00093 
00094 /* GF_MULTIPLY
00095  *
00096  * multiply two bytes represented in GF(2**8), mod (x**4 + 1)
00097  */
00098 PRUint8 gf_multiply(PRUint8 a, PRUint8 b)
00099 {
00100     PRUint8 res = 0;
00101     while (b > 0) {
00102        res = (b & 0x01) ? res ^ a : res;
00103        a = (a & 0x80) ? ((a << 1) ^ 0x1b) : (a << 1);
00104        b >>= 1;
00105     }
00106     return res;
00107 }
00108 
00109 void
00110 make_T_Table(char *table, const PRUint8 Sx[256], FILE *file,
00111              unsigned char m0, unsigned char m1, 
00112              unsigned char m2, unsigned char m3)
00113 {
00114     PRUint32 Ti;
00115     int i;
00116     fprintf(file, "#ifdef IS_LITTLE_ENDIAN\n");
00117     fprintf(file, "static const PRUint32 _T%s[256] = \n{\n", table);
00118     for (i=0; i<256; i++) {
00119        Ti = WORD_LE( gf_multiply(Sx[i], m0),
00120                      gf_multiply(Sx[i], m1),
00121                      gf_multiply(Sx[i], m2),
00122                      gf_multiply(Sx[i], m3) );
00123        if (Ti == 0)
00124            fprintf(file, "0x00000000%c%c", (i==255)?' ':',',
00125                                            (i%6==5)?'\n':' ');
00126        else
00127            fprintf(file, "%#.8x%c%c", Ti, (i==255)?' ':',',
00128                                           (i%6==5)?'\n':' ');
00129     }
00130     fprintf(file, "\n};\n");
00131     fprintf(file, "#else\n");
00132     fprintf(file, "static const PRUint32 _T%s[256] = \n{\n", table);
00133     for (i=0; i<256; i++) {
00134        Ti = WORD_BE( gf_multiply(Sx[i], m0),
00135                      gf_multiply(Sx[i], m1),
00136                      gf_multiply(Sx[i], m2),
00137                      gf_multiply(Sx[i], m3) );
00138        if (Ti == 0)
00139            fprintf(file, "0x00000000%c%c", (i==255)?' ':',',
00140                                            (i%6==5)?'\n':' ');
00141        else
00142            fprintf(file, "%#.8x%c%c", Ti, (i==255)?' ':',',
00143                                           (i%6==5)?'\n':' ');
00144     }
00145     fprintf(file, "\n};\n");
00146     fprintf(file, "#endif\n\n");
00147 }
00148 
00149 void make_InvMixCol_Table(int num, FILE *file, PRUint8 m0, PRUint8 m1, PRUint8 m2, PRUint8 m3)
00150 {
00151     PRUint16 i;
00152     PRUint8 b0, b1, b2, b3;
00153     fprintf(file, "#ifdef IS_LITTLE_ENDIAN\n");
00154     fprintf(file, "static const PRUint32 _IMXC%d[256] = \n{\n", num);
00155     for (i=0; i<256; i++) {
00156        b0 = gf_multiply(i, m0);
00157        b1 = gf_multiply(i, m1);
00158        b2 = gf_multiply(i, m2);
00159        b3 = gf_multiply(i, m3);
00160        fprintf(file, "0x%.2x%.2x%.2x%.2x%c%c", b3, b2, b1, b0, (i==255)?' ':',', (i%6==5)?'\n':' ');
00161     }
00162     fprintf(file, "\n};\n");
00163     fprintf(file, "#else\n");
00164     fprintf(file, "static const PRUint32 _IMXC%d[256] = \n{\n", num);
00165     for (i=0; i<256; i++) {
00166        b0 = gf_multiply(i, m0);
00167        b1 = gf_multiply(i, m1);
00168        b2 = gf_multiply(i, m2);
00169        b3 = gf_multiply(i, m3);
00170        fprintf(file, "0x%.2x%.2x%.2x%.2x%c%c", b0, b1, b2, b3, (i==255)?' ':',', (i%6==5)?'\n':' ');
00171     }
00172     fprintf(file, "\n};\n");
00173     fprintf(file, "#endif\n\n");
00174 }
00175 
00176 int main()
00177 {
00178     int i, j;
00179     PRUint8 cur, last;
00180     PRUint32 tmp;
00181     FILE *optfile;
00182     optfile = fopen("rijndael32.tab", "w");
00183     /* output S, if there are no T tables */
00184     fprintf(optfile, "#ifndef RIJNDAEL_INCLUDE_TABLES\n");
00185     fprintf(optfile, "static const PRUint8 _S[256] = \n{\n");
00186     for (i=0; i<256; i++) {
00187        fprintf(optfile, "%3d%c%c", __S[i],(i==255)?' ':',', 
00188                                    (i%16==15)?'\n':' ');
00189     }
00190     fprintf(optfile, "};\n#endif /* not RIJNDAEL_INCLUDE_TABLES */\n\n");
00191     /* output S**-1 */
00192     fprintf(optfile, "static const PRUint8 _SInv[256] = \n{\n");
00193     for (i=0; i<256; i++) {
00194        fprintf(optfile, "%3d%c%c", __SInv[i],(i==255)?' ':',', 
00195                                    (i%16==15)?'\n':' ');
00196     }
00197     fprintf(optfile, "};\n\n");
00198     fprintf(optfile, "#ifdef RIJNDAEL_INCLUDE_TABLES\n");
00199     /* The 32-bit word tables for optimized implementation */
00200     /* T0 = [ S[a] * 02, S[a], S[a], S[a] * 03 ] */
00201     make_T_Table("0", __S, optfile, 0x02, 0x01, 0x01, 0x03);
00202     /* T1 = [ S[a] * 03, S[a] * 02, S[a], S[a] ] */
00203     make_T_Table("1", __S, optfile, 0x03, 0x02, 0x01, 0x01);
00204     /* T2 = [ S[a], S[a] * 03, S[a] * 02, S[a] ] */
00205     make_T_Table("2", __S, optfile, 0x01, 0x03, 0x02, 0x01);
00206     /* T3 = [ S[a], S[a], S[a] * 03, S[a] * 02 ] */
00207     make_T_Table("3", __S, optfile, 0x01, 0x01, 0x03, 0x02);
00208     /* TInv0 = [ Si[a] * 0E, Si[a] * 09, Si[a] * 0D, Si[a] * 0B ] */
00209     make_T_Table("Inv0", __SInv, optfile, 0x0e, 0x09, 0x0d, 0x0b);
00210     /* TInv1 = [ Si[a] * 0B, Si[a] * 0E, Si[a] * 09, Si[a] * 0D ] */
00211     make_T_Table("Inv1", __SInv, optfile, 0x0b, 0x0e, 0x09, 0x0d);
00212     /* TInv2 = [ Si[a] * 0D, Si[a] * 0B, Si[a] * 0E, Si[a] * 09 ] */
00213     make_T_Table("Inv2", __SInv, optfile, 0x0d, 0x0b, 0x0e, 0x09);
00214     /* TInv3 = [ Si[a] * 09, Si[a] * 0D, Si[a] * 0B, Si[a] * 0E ] */
00215     make_T_Table("Inv3", __SInv, optfile, 0x09, 0x0d, 0x0b, 0x0e);
00216     /* byte multiply tables for inverse key expansion (mimics InvMixColumn) */
00217     make_InvMixCol_Table(0, optfile, 0x0e, 0x09, 0x0d, 0x0b);
00218     make_InvMixCol_Table(1, optfile, 0x0b, 0x0E, 0x09, 0x0d);
00219     make_InvMixCol_Table(2, optfile, 0x0d, 0x0b, 0x0e, 0x09);
00220     make_InvMixCol_Table(3, optfile, 0x09, 0x0d, 0x0b, 0x0e);
00221     fprintf(optfile, "#endif /* RIJNDAEL_INCLUDE_TABLES */\n\n");
00222     /* round constants for key expansion */
00223     fprintf(optfile, "#ifdef IS_LITTLE_ENDIAN\n");
00224     fprintf(optfile, "static const PRUint32 Rcon[30] = {\n");
00225     cur = 0x01;
00226     for (i=0; i<30; i++) {
00227        fprintf(optfile, "%#.8x%c%c", WORD_LE(cur, 0, 0, 0), 
00228                                        (i==29)?' ':',', (i%6==5)?'\n':' ');
00229        last = cur;
00230        cur = gf_multiply(last, 0x02);
00231     }
00232     fprintf(optfile, "};\n");
00233     fprintf(optfile, "#else\n");
00234     fprintf(optfile, "static const PRUint32 Rcon[30] = {\n");
00235     cur = 0x01;
00236     for (i=0; i<30; i++) {
00237        fprintf(optfile, "%#.8x%c%c", WORD_BE(cur, 0, 0, 0), 
00238                                        (i==29)?' ':',', (i%6==5)?'\n':' ');
00239        last = cur;
00240        cur = gf_multiply(last, 0x02);
00241     }
00242     fprintf(optfile, "};\n");
00243     fprintf(optfile, "#endif\n\n");
00244     fclose(optfile);
00245     return 0;
00246 }