001: package org.bouncycastle.crypto.engines;
002:
003: import org.bouncycastle.crypto.BlockCipher;
004: import org.bouncycastle.crypto.CipherParameters;
005: import org.bouncycastle.crypto.DataLengthException;
006: import org.bouncycastle.crypto.params.KeyParameter;
007:
008: /**
009: * an implementation of Rijndael, based on the documentation and reference implementation
010: * by Paulo Barreto, Vincent Rijmen, for v2.0 August '99.
011: * <p>
012: * Note: this implementation is based on information prior to final NIST publication.
013: */
014: public class RijndaelEngine implements BlockCipher {
015: private static final int MAXROUNDS = 14;
016:
017: private static final int MAXKC = (256 / 4);
018:
019: private static final byte[] logtable = { (byte) 0, (byte) 0,
020: (byte) 25, (byte) 1, (byte) 50, (byte) 2, (byte) 26,
021: (byte) 198, (byte) 75, (byte) 199, (byte) 27, (byte) 104,
022: (byte) 51, (byte) 238, (byte) 223, (byte) 3, (byte) 100,
023: (byte) 4, (byte) 224, (byte) 14, (byte) 52, (byte) 141,
024: (byte) 129, (byte) 239, (byte) 76, (byte) 113, (byte) 8,
025: (byte) 200, (byte) 248, (byte) 105, (byte) 28, (byte) 193,
026: (byte) 125, (byte) 194, (byte) 29, (byte) 181, (byte) 249,
027: (byte) 185, (byte) 39, (byte) 106, (byte) 77, (byte) 228,
028: (byte) 166, (byte) 114, (byte) 154, (byte) 201, (byte) 9,
029: (byte) 120, (byte) 101, (byte) 47, (byte) 138, (byte) 5,
030: (byte) 33, (byte) 15, (byte) 225, (byte) 36, (byte) 18,
031: (byte) 240, (byte) 130, (byte) 69, (byte) 53, (byte) 147,
032: (byte) 218, (byte) 142, (byte) 150, (byte) 143, (byte) 219,
033: (byte) 189, (byte) 54, (byte) 208, (byte) 206, (byte) 148,
034: (byte) 19, (byte) 92, (byte) 210, (byte) 241, (byte) 64,
035: (byte) 70, (byte) 131, (byte) 56, (byte) 102, (byte) 221,
036: (byte) 253, (byte) 48, (byte) 191, (byte) 6, (byte) 139,
037: (byte) 98, (byte) 179, (byte) 37, (byte) 226, (byte) 152,
038: (byte) 34, (byte) 136, (byte) 145, (byte) 16, (byte) 126,
039: (byte) 110, (byte) 72, (byte) 195, (byte) 163, (byte) 182,
040: (byte) 30, (byte) 66, (byte) 58, (byte) 107, (byte) 40,
041: (byte) 84, (byte) 250, (byte) 133, (byte) 61, (byte) 186,
042: (byte) 43, (byte) 121, (byte) 10, (byte) 21, (byte) 155,
043: (byte) 159, (byte) 94, (byte) 202, (byte) 78, (byte) 212,
044: (byte) 172, (byte) 229, (byte) 243, (byte) 115, (byte) 167,
045: (byte) 87, (byte) 175, (byte) 88, (byte) 168, (byte) 80,
046: (byte) 244, (byte) 234, (byte) 214, (byte) 116, (byte) 79,
047: (byte) 174, (byte) 233, (byte) 213, (byte) 231, (byte) 230,
048: (byte) 173, (byte) 232, (byte) 44, (byte) 215, (byte) 117,
049: (byte) 122, (byte) 235, (byte) 22, (byte) 11, (byte) 245,
050: (byte) 89, (byte) 203, (byte) 95, (byte) 176, (byte) 156,
051: (byte) 169, (byte) 81, (byte) 160, (byte) 127, (byte) 12,
052: (byte) 246, (byte) 111, (byte) 23, (byte) 196, (byte) 73,
053: (byte) 236, (byte) 216, (byte) 67, (byte) 31, (byte) 45,
054: (byte) 164, (byte) 118, (byte) 123, (byte) 183, (byte) 204,
055: (byte) 187, (byte) 62, (byte) 90, (byte) 251, (byte) 96,
056: (byte) 177, (byte) 134, (byte) 59, (byte) 82, (byte) 161,
057: (byte) 108, (byte) 170, (byte) 85, (byte) 41, (byte) 157,
058: (byte) 151, (byte) 178, (byte) 135, (byte) 144, (byte) 97,
059: (byte) 190, (byte) 220, (byte) 252, (byte) 188, (byte) 149,
060: (byte) 207, (byte) 205, (byte) 55, (byte) 63, (byte) 91,
061: (byte) 209, (byte) 83, (byte) 57, (byte) 132, (byte) 60,
062: (byte) 65, (byte) 162, (byte) 109, (byte) 71, (byte) 20,
063: (byte) 42, (byte) 158, (byte) 93, (byte) 86, (byte) 242,
064: (byte) 211, (byte) 171, (byte) 68, (byte) 17, (byte) 146,
065: (byte) 217, (byte) 35, (byte) 32, (byte) 46, (byte) 137,
066: (byte) 180, (byte) 124, (byte) 184, (byte) 38, (byte) 119,
067: (byte) 153, (byte) 227, (byte) 165, (byte) 103, (byte) 74,
068: (byte) 237, (byte) 222, (byte) 197, (byte) 49, (byte) 254,
069: (byte) 24, (byte) 13, (byte) 99, (byte) 140, (byte) 128,
070: (byte) 192, (byte) 247, (byte) 112, (byte) 7 };
071:
072: private static final byte[] aLogtable = { (byte) 0, (byte) 3,
073: (byte) 5, (byte) 15, (byte) 17, (byte) 51, (byte) 85,
074: (byte) 255, (byte) 26, (byte) 46, (byte) 114, (byte) 150,
075: (byte) 161, (byte) 248, (byte) 19, (byte) 53, (byte) 95,
076: (byte) 225, (byte) 56, (byte) 72, (byte) 216, (byte) 115,
077: (byte) 149, (byte) 164, (byte) 247, (byte) 2, (byte) 6,
078: (byte) 10, (byte) 30, (byte) 34, (byte) 102, (byte) 170,
079: (byte) 229, (byte) 52, (byte) 92, (byte) 228, (byte) 55,
080: (byte) 89, (byte) 235, (byte) 38, (byte) 106, (byte) 190,
081: (byte) 217, (byte) 112, (byte) 144, (byte) 171, (byte) 230,
082: (byte) 49, (byte) 83, (byte) 245, (byte) 4, (byte) 12,
083: (byte) 20, (byte) 60, (byte) 68, (byte) 204, (byte) 79,
084: (byte) 209, (byte) 104, (byte) 184, (byte) 211, (byte) 110,
085: (byte) 178, (byte) 205, (byte) 76, (byte) 212, (byte) 103,
086: (byte) 169, (byte) 224, (byte) 59, (byte) 77, (byte) 215,
087: (byte) 98, (byte) 166, (byte) 241, (byte) 8, (byte) 24,
088: (byte) 40, (byte) 120, (byte) 136, (byte) 131, (byte) 158,
089: (byte) 185, (byte) 208, (byte) 107, (byte) 189, (byte) 220,
090: (byte) 127, (byte) 129, (byte) 152, (byte) 179, (byte) 206,
091: (byte) 73, (byte) 219, (byte) 118, (byte) 154, (byte) 181,
092: (byte) 196, (byte) 87, (byte) 249, (byte) 16, (byte) 48,
093: (byte) 80, (byte) 240, (byte) 11, (byte) 29, (byte) 39,
094: (byte) 105, (byte) 187, (byte) 214, (byte) 97, (byte) 163,
095: (byte) 254, (byte) 25, (byte) 43, (byte) 125, (byte) 135,
096: (byte) 146, (byte) 173, (byte) 236, (byte) 47, (byte) 113,
097: (byte) 147, (byte) 174, (byte) 233, (byte) 32, (byte) 96,
098: (byte) 160, (byte) 251, (byte) 22, (byte) 58, (byte) 78,
099: (byte) 210, (byte) 109, (byte) 183, (byte) 194, (byte) 93,
100: (byte) 231, (byte) 50, (byte) 86, (byte) 250, (byte) 21,
101: (byte) 63, (byte) 65, (byte) 195, (byte) 94, (byte) 226,
102: (byte) 61, (byte) 71, (byte) 201, (byte) 64, (byte) 192,
103: (byte) 91, (byte) 237, (byte) 44, (byte) 116, (byte) 156,
104: (byte) 191, (byte) 218, (byte) 117, (byte) 159, (byte) 186,
105: (byte) 213, (byte) 100, (byte) 172, (byte) 239, (byte) 42,
106: (byte) 126, (byte) 130, (byte) 157, (byte) 188, (byte) 223,
107: (byte) 122, (byte) 142, (byte) 137, (byte) 128, (byte) 155,
108: (byte) 182, (byte) 193, (byte) 88, (byte) 232, (byte) 35,
109: (byte) 101, (byte) 175, (byte) 234, (byte) 37, (byte) 111,
110: (byte) 177, (byte) 200, (byte) 67, (byte) 197, (byte) 84,
111: (byte) 252, (byte) 31, (byte) 33, (byte) 99, (byte) 165,
112: (byte) 244, (byte) 7, (byte) 9, (byte) 27, (byte) 45,
113: (byte) 119, (byte) 153, (byte) 176, (byte) 203, (byte) 70,
114: (byte) 202, (byte) 69, (byte) 207, (byte) 74, (byte) 222,
115: (byte) 121, (byte) 139, (byte) 134, (byte) 145, (byte) 168,
116: (byte) 227, (byte) 62, (byte) 66, (byte) 198, (byte) 81,
117: (byte) 243, (byte) 14, (byte) 18, (byte) 54, (byte) 90,
118: (byte) 238, (byte) 41, (byte) 123, (byte) 141, (byte) 140,
119: (byte) 143, (byte) 138, (byte) 133, (byte) 148, (byte) 167,
120: (byte) 242, (byte) 13, (byte) 23, (byte) 57, (byte) 75,
121: (byte) 221, (byte) 124, (byte) 132, (byte) 151, (byte) 162,
122: (byte) 253, (byte) 28, (byte) 36, (byte) 108, (byte) 180,
123: (byte) 199, (byte) 82, (byte) 246, (byte) 1, (byte) 3,
124: (byte) 5, (byte) 15, (byte) 17, (byte) 51, (byte) 85,
125: (byte) 255, (byte) 26, (byte) 46, (byte) 114, (byte) 150,
126: (byte) 161, (byte) 248, (byte) 19, (byte) 53, (byte) 95,
127: (byte) 225, (byte) 56, (byte) 72, (byte) 216, (byte) 115,
128: (byte) 149, (byte) 164, (byte) 247, (byte) 2, (byte) 6,
129: (byte) 10, (byte) 30, (byte) 34, (byte) 102, (byte) 170,
130: (byte) 229, (byte) 52, (byte) 92, (byte) 228, (byte) 55,
131: (byte) 89, (byte) 235, (byte) 38, (byte) 106, (byte) 190,
132: (byte) 217, (byte) 112, (byte) 144, (byte) 171, (byte) 230,
133: (byte) 49, (byte) 83, (byte) 245, (byte) 4, (byte) 12,
134: (byte) 20, (byte) 60, (byte) 68, (byte) 204, (byte) 79,
135: (byte) 209, (byte) 104, (byte) 184, (byte) 211, (byte) 110,
136: (byte) 178, (byte) 205, (byte) 76, (byte) 212, (byte) 103,
137: (byte) 169, (byte) 224, (byte) 59, (byte) 77, (byte) 215,
138: (byte) 98, (byte) 166, (byte) 241, (byte) 8, (byte) 24,
139: (byte) 40, (byte) 120, (byte) 136, (byte) 131, (byte) 158,
140: (byte) 185, (byte) 208, (byte) 107, (byte) 189, (byte) 220,
141: (byte) 127, (byte) 129, (byte) 152, (byte) 179, (byte) 206,
142: (byte) 73, (byte) 219, (byte) 118, (byte) 154, (byte) 181,
143: (byte) 196, (byte) 87, (byte) 249, (byte) 16, (byte) 48,
144: (byte) 80, (byte) 240, (byte) 11, (byte) 29, (byte) 39,
145: (byte) 105, (byte) 187, (byte) 214, (byte) 97, (byte) 163,
146: (byte) 254, (byte) 25, (byte) 43, (byte) 125, (byte) 135,
147: (byte) 146, (byte) 173, (byte) 236, (byte) 47, (byte) 113,
148: (byte) 147, (byte) 174, (byte) 233, (byte) 32, (byte) 96,
149: (byte) 160, (byte) 251, (byte) 22, (byte) 58, (byte) 78,
150: (byte) 210, (byte) 109, (byte) 183, (byte) 194, (byte) 93,
151: (byte) 231, (byte) 50, (byte) 86, (byte) 250, (byte) 21,
152: (byte) 63, (byte) 65, (byte) 195, (byte) 94, (byte) 226,
153: (byte) 61, (byte) 71, (byte) 201, (byte) 64, (byte) 192,
154: (byte) 91, (byte) 237, (byte) 44, (byte) 116, (byte) 156,
155: (byte) 191, (byte) 218, (byte) 117, (byte) 159, (byte) 186,
156: (byte) 213, (byte) 100, (byte) 172, (byte) 239, (byte) 42,
157: (byte) 126, (byte) 130, (byte) 157, (byte) 188, (byte) 223,
158: (byte) 122, (byte) 142, (byte) 137, (byte) 128, (byte) 155,
159: (byte) 182, (byte) 193, (byte) 88, (byte) 232, (byte) 35,
160: (byte) 101, (byte) 175, (byte) 234, (byte) 37, (byte) 111,
161: (byte) 177, (byte) 200, (byte) 67, (byte) 197, (byte) 84,
162: (byte) 252, (byte) 31, (byte) 33, (byte) 99, (byte) 165,
163: (byte) 244, (byte) 7, (byte) 9, (byte) 27, (byte) 45,
164: (byte) 119, (byte) 153, (byte) 176, (byte) 203, (byte) 70,
165: (byte) 202, (byte) 69, (byte) 207, (byte) 74, (byte) 222,
166: (byte) 121, (byte) 139, (byte) 134, (byte) 145, (byte) 168,
167: (byte) 227, (byte) 62, (byte) 66, (byte) 198, (byte) 81,
168: (byte) 243, (byte) 14, (byte) 18, (byte) 54, (byte) 90,
169: (byte) 238, (byte) 41, (byte) 123, (byte) 141, (byte) 140,
170: (byte) 143, (byte) 138, (byte) 133, (byte) 148, (byte) 167,
171: (byte) 242, (byte) 13, (byte) 23, (byte) 57, (byte) 75,
172: (byte) 221, (byte) 124, (byte) 132, (byte) 151, (byte) 162,
173: (byte) 253, (byte) 28, (byte) 36, (byte) 108, (byte) 180,
174: (byte) 199, (byte) 82, (byte) 246, (byte) 1, };
175:
176: private static final byte[] S = { (byte) 99, (byte) 124,
177: (byte) 119, (byte) 123, (byte) 242, (byte) 107, (byte) 111,
178: (byte) 197, (byte) 48, (byte) 1, (byte) 103, (byte) 43,
179: (byte) 254, (byte) 215, (byte) 171, (byte) 118, (byte) 202,
180: (byte) 130, (byte) 201, (byte) 125, (byte) 250, (byte) 89,
181: (byte) 71, (byte) 240, (byte) 173, (byte) 212, (byte) 162,
182: (byte) 175, (byte) 156, (byte) 164, (byte) 114, (byte) 192,
183: (byte) 183, (byte) 253, (byte) 147, (byte) 38, (byte) 54,
184: (byte) 63, (byte) 247, (byte) 204, (byte) 52, (byte) 165,
185: (byte) 229, (byte) 241, (byte) 113, (byte) 216, (byte) 49,
186: (byte) 21, (byte) 4, (byte) 199, (byte) 35, (byte) 195,
187: (byte) 24, (byte) 150, (byte) 5, (byte) 154, (byte) 7,
188: (byte) 18, (byte) 128, (byte) 226, (byte) 235, (byte) 39,
189: (byte) 178, (byte) 117, (byte) 9, (byte) 131, (byte) 44,
190: (byte) 26, (byte) 27, (byte) 110, (byte) 90, (byte) 160,
191: (byte) 82, (byte) 59, (byte) 214, (byte) 179, (byte) 41,
192: (byte) 227, (byte) 47, (byte) 132, (byte) 83, (byte) 209,
193: (byte) 0, (byte) 237, (byte) 32, (byte) 252, (byte) 177,
194: (byte) 91, (byte) 106, (byte) 203, (byte) 190, (byte) 57,
195: (byte) 74, (byte) 76, (byte) 88, (byte) 207, (byte) 208,
196: (byte) 239, (byte) 170, (byte) 251, (byte) 67, (byte) 77,
197: (byte) 51, (byte) 133, (byte) 69, (byte) 249, (byte) 2,
198: (byte) 127, (byte) 80, (byte) 60, (byte) 159, (byte) 168,
199: (byte) 81, (byte) 163, (byte) 64, (byte) 143, (byte) 146,
200: (byte) 157, (byte) 56, (byte) 245, (byte) 188, (byte) 182,
201: (byte) 218, (byte) 33, (byte) 16, (byte) 255, (byte) 243,
202: (byte) 210, (byte) 205, (byte) 12, (byte) 19, (byte) 236,
203: (byte) 95, (byte) 151, (byte) 68, (byte) 23, (byte) 196,
204: (byte) 167, (byte) 126, (byte) 61, (byte) 100, (byte) 93,
205: (byte) 25, (byte) 115, (byte) 96, (byte) 129, (byte) 79,
206: (byte) 220, (byte) 34, (byte) 42, (byte) 144, (byte) 136,
207: (byte) 70, (byte) 238, (byte) 184, (byte) 20, (byte) 222,
208: (byte) 94, (byte) 11, (byte) 219, (byte) 224, (byte) 50,
209: (byte) 58, (byte) 10, (byte) 73, (byte) 6, (byte) 36,
210: (byte) 92, (byte) 194, (byte) 211, (byte) 172, (byte) 98,
211: (byte) 145, (byte) 149, (byte) 228, (byte) 121, (byte) 231,
212: (byte) 200, (byte) 55, (byte) 109, (byte) 141, (byte) 213,
213: (byte) 78, (byte) 169, (byte) 108, (byte) 86, (byte) 244,
214: (byte) 234, (byte) 101, (byte) 122, (byte) 174, (byte) 8,
215: (byte) 186, (byte) 120, (byte) 37, (byte) 46, (byte) 28,
216: (byte) 166, (byte) 180, (byte) 198, (byte) 232, (byte) 221,
217: (byte) 116, (byte) 31, (byte) 75, (byte) 189, (byte) 139,
218: (byte) 138, (byte) 112, (byte) 62, (byte) 181, (byte) 102,
219: (byte) 72, (byte) 3, (byte) 246, (byte) 14, (byte) 97,
220: (byte) 53, (byte) 87, (byte) 185, (byte) 134, (byte) 193,
221: (byte) 29, (byte) 158, (byte) 225, (byte) 248, (byte) 152,
222: (byte) 17, (byte) 105, (byte) 217, (byte) 142, (byte) 148,
223: (byte) 155, (byte) 30, (byte) 135, (byte) 233, (byte) 206,
224: (byte) 85, (byte) 40, (byte) 223, (byte) 140, (byte) 161,
225: (byte) 137, (byte) 13, (byte) 191, (byte) 230, (byte) 66,
226: (byte) 104, (byte) 65, (byte) 153, (byte) 45, (byte) 15,
227: (byte) 176, (byte) 84, (byte) 187, (byte) 22, };
228:
229: private static final byte[] Si = { (byte) 82, (byte) 9, (byte) 106,
230: (byte) 213, (byte) 48, (byte) 54, (byte) 165, (byte) 56,
231: (byte) 191, (byte) 64, (byte) 163, (byte) 158, (byte) 129,
232: (byte) 243, (byte) 215, (byte) 251, (byte) 124, (byte) 227,
233: (byte) 57, (byte) 130, (byte) 155, (byte) 47, (byte) 255,
234: (byte) 135, (byte) 52, (byte) 142, (byte) 67, (byte) 68,
235: (byte) 196, (byte) 222, (byte) 233, (byte) 203, (byte) 84,
236: (byte) 123, (byte) 148, (byte) 50, (byte) 166, (byte) 194,
237: (byte) 35, (byte) 61, (byte) 238, (byte) 76, (byte) 149,
238: (byte) 11, (byte) 66, (byte) 250, (byte) 195, (byte) 78,
239: (byte) 8, (byte) 46, (byte) 161, (byte) 102, (byte) 40,
240: (byte) 217, (byte) 36, (byte) 178, (byte) 118, (byte) 91,
241: (byte) 162, (byte) 73, (byte) 109, (byte) 139, (byte) 209,
242: (byte) 37, (byte) 114, (byte) 248, (byte) 246, (byte) 100,
243: (byte) 134, (byte) 104, (byte) 152, (byte) 22, (byte) 212,
244: (byte) 164, (byte) 92, (byte) 204, (byte) 93, (byte) 101,
245: (byte) 182, (byte) 146, (byte) 108, (byte) 112, (byte) 72,
246: (byte) 80, (byte) 253, (byte) 237, (byte) 185, (byte) 218,
247: (byte) 94, (byte) 21, (byte) 70, (byte) 87, (byte) 167,
248: (byte) 141, (byte) 157, (byte) 132, (byte) 144, (byte) 216,
249: (byte) 171, (byte) 0, (byte) 140, (byte) 188, (byte) 211,
250: (byte) 10, (byte) 247, (byte) 228, (byte) 88, (byte) 5,
251: (byte) 184, (byte) 179, (byte) 69, (byte) 6, (byte) 208,
252: (byte) 44, (byte) 30, (byte) 143, (byte) 202, (byte) 63,
253: (byte) 15, (byte) 2, (byte) 193, (byte) 175, (byte) 189,
254: (byte) 3, (byte) 1, (byte) 19, (byte) 138, (byte) 107,
255: (byte) 58, (byte) 145, (byte) 17, (byte) 65, (byte) 79,
256: (byte) 103, (byte) 220, (byte) 234, (byte) 151, (byte) 242,
257: (byte) 207, (byte) 206, (byte) 240, (byte) 180, (byte) 230,
258: (byte) 115, (byte) 150, (byte) 172, (byte) 116, (byte) 34,
259: (byte) 231, (byte) 173, (byte) 53, (byte) 133, (byte) 226,
260: (byte) 249, (byte) 55, (byte) 232, (byte) 28, (byte) 117,
261: (byte) 223, (byte) 110, (byte) 71, (byte) 241, (byte) 26,
262: (byte) 113, (byte) 29, (byte) 41, (byte) 197, (byte) 137,
263: (byte) 111, (byte) 183, (byte) 98, (byte) 14, (byte) 170,
264: (byte) 24, (byte) 190, (byte) 27, (byte) 252, (byte) 86,
265: (byte) 62, (byte) 75, (byte) 198, (byte) 210, (byte) 121,
266: (byte) 32, (byte) 154, (byte) 219, (byte) 192, (byte) 254,
267: (byte) 120, (byte) 205, (byte) 90, (byte) 244, (byte) 31,
268: (byte) 221, (byte) 168, (byte) 51, (byte) 136, (byte) 7,
269: (byte) 199, (byte) 49, (byte) 177, (byte) 18, (byte) 16,
270: (byte) 89, (byte) 39, (byte) 128, (byte) 236, (byte) 95,
271: (byte) 96, (byte) 81, (byte) 127, (byte) 169, (byte) 25,
272: (byte) 181, (byte) 74, (byte) 13, (byte) 45, (byte) 229,
273: (byte) 122, (byte) 159, (byte) 147, (byte) 201, (byte) 156,
274: (byte) 239, (byte) 160, (byte) 224, (byte) 59, (byte) 77,
275: (byte) 174, (byte) 42, (byte) 245, (byte) 176, (byte) 200,
276: (byte) 235, (byte) 187, (byte) 60, (byte) 131, (byte) 83,
277: (byte) 153, (byte) 97, (byte) 23, (byte) 43, (byte) 4,
278: (byte) 126, (byte) 186, (byte) 119, (byte) 214, (byte) 38,
279: (byte) 225, (byte) 105, (byte) 20, (byte) 99, (byte) 85,
280: (byte) 33, (byte) 12, (byte) 125, };
281:
282: private static final int[] rcon = { 0x01, 0x02, 0x04, 0x08, 0x10,
283: 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
284: 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
285: 0x7d, 0xfa, 0xef, 0xc5, 0x91 };
286:
287: static byte[][] shifts0 = { { 0, 8, 16, 24 }, { 0, 8, 16, 24 },
288: { 0, 8, 16, 24 }, { 0, 8, 16, 32 }, { 0, 8, 24, 32 } };
289:
290: static byte[][] shifts1 = { { 0, 24, 16, 8 }, { 0, 32, 24, 16 },
291: { 0, 40, 32, 24 }, { 0, 48, 40, 24 }, { 0, 56, 40, 32 } };
292:
293: /**
294: * multiply two elements of GF(2^m)
295: * needed for MixColumn and InvMixColumn
296: */
297: private byte mul0x2(int b) {
298: if (b != 0) {
299: return aLogtable[25 + (logtable[b] & 0xff)];
300: } else {
301: return 0;
302: }
303: }
304:
305: private byte mul0x3(int b) {
306: if (b != 0) {
307: return aLogtable[1 + (logtable[b] & 0xff)];
308: } else {
309: return 0;
310: }
311: }
312:
313: private byte mul0x9(int b) {
314: if (b >= 0) {
315: return aLogtable[199 + b];
316: } else {
317: return 0;
318: }
319: }
320:
321: private byte mul0xb(int b) {
322: if (b >= 0) {
323: return aLogtable[104 + b];
324: } else {
325: return 0;
326: }
327: }
328:
329: private byte mul0xd(int b) {
330: if (b >= 0) {
331: return aLogtable[238 + b];
332: } else {
333: return 0;
334: }
335: }
336:
337: private byte mul0xe(int b) {
338: if (b >= 0) {
339: return aLogtable[223 + b];
340: } else {
341: return 0;
342: }
343: }
344:
345: /**
346: * xor corresponding text input and round key input bytes
347: */
348: private void KeyAddition(long[] rk) {
349: A0 ^= rk[0];
350: A1 ^= rk[1];
351: A2 ^= rk[2];
352: A3 ^= rk[3];
353: }
354:
355: private long shift(long r, int shift) {
356: return (((r >>> shift) | (r << (BC - shift)))) & BC_MASK;
357: }
358:
359: /**
360: * Row 0 remains unchanged
361: * The other three rows are shifted a variable amount
362: */
363: private void ShiftRow(byte[] shiftsSC) {
364: A1 = shift(A1, shiftsSC[1]);
365: A2 = shift(A2, shiftsSC[2]);
366: A3 = shift(A3, shiftsSC[3]);
367: }
368:
369: private long applyS(long r, byte[] box) {
370: long res = 0;
371:
372: for (int j = 0; j < BC; j += 8) {
373: res |= (long) (box[(int) ((r >> j) & 0xff)] & 0xff) << j;
374: }
375:
376: return res;
377: }
378:
379: /**
380: * Replace every byte of the input by the byte at that place
381: * in the nonlinear S-box
382: */
383: private void Substitution(byte[] box) {
384: A0 = applyS(A0, box);
385: A1 = applyS(A1, box);
386: A2 = applyS(A2, box);
387: A3 = applyS(A3, box);
388: }
389:
390: /**
391: * Mix the bytes of every column in a linear way
392: */
393: private void MixColumn() {
394: long r0, r1, r2, r3;
395:
396: r0 = r1 = r2 = r3 = 0;
397:
398: for (int j = 0; j < BC; j += 8) {
399: int a0 = (int) ((A0 >> j) & 0xff);
400: int a1 = (int) ((A1 >> j) & 0xff);
401: int a2 = (int) ((A2 >> j) & 0xff);
402: int a3 = (int) ((A3 >> j) & 0xff);
403:
404: r0 |= (long) ((mul0x2(a0) ^ mul0x3(a1) ^ a2 ^ a3) & 0xff) << j;
405:
406: r1 |= (long) ((mul0x2(a1) ^ mul0x3(a2) ^ a3 ^ a0) & 0xff) << j;
407:
408: r2 |= (long) ((mul0x2(a2) ^ mul0x3(a3) ^ a0 ^ a1) & 0xff) << j;
409:
410: r3 |= (long) ((mul0x2(a3) ^ mul0x3(a0) ^ a1 ^ a2) & 0xff) << j;
411: }
412:
413: A0 = r0;
414: A1 = r1;
415: A2 = r2;
416: A3 = r3;
417: }
418:
419: /**
420: * Mix the bytes of every column in a linear way
421: * This is the opposite operation of Mixcolumn
422: */
423: private void InvMixColumn() {
424: long r0, r1, r2, r3;
425:
426: r0 = r1 = r2 = r3 = 0;
427: for (int j = 0; j < BC; j += 8) {
428: int a0 = (int) ((A0 >> j) & 0xff);
429: int a1 = (int) ((A1 >> j) & 0xff);
430: int a2 = (int) ((A2 >> j) & 0xff);
431: int a3 = (int) ((A3 >> j) & 0xff);
432:
433: //
434: // pre-lookup the log table
435: //
436: a0 = (a0 != 0) ? (logtable[a0 & 0xff] & 0xff) : -1;
437: a1 = (a1 != 0) ? (logtable[a1 & 0xff] & 0xff) : -1;
438: a2 = (a2 != 0) ? (logtable[a2 & 0xff] & 0xff) : -1;
439: a3 = (a3 != 0) ? (logtable[a3 & 0xff] & 0xff) : -1;
440:
441: r0 |= (long) ((mul0xe(a0) ^ mul0xb(a1) ^ mul0xd(a2) ^ mul0x9(a3)) & 0xff) << j;
442:
443: r1 |= (long) ((mul0xe(a1) ^ mul0xb(a2) ^ mul0xd(a3) ^ mul0x9(a0)) & 0xff) << j;
444:
445: r2 |= (long) ((mul0xe(a2) ^ mul0xb(a3) ^ mul0xd(a0) ^ mul0x9(a1)) & 0xff) << j;
446:
447: r3 |= (long) ((mul0xe(a3) ^ mul0xb(a0) ^ mul0xd(a1) ^ mul0x9(a2)) & 0xff) << j;
448: }
449:
450: A0 = r0;
451: A1 = r1;
452: A2 = r2;
453: A3 = r3;
454: }
455:
456: /**
457: * Calculate the necessary round keys
458: * The number of calculations depends on keyBits and blockBits
459: */
460: private long[][] generateWorkingKey(byte[] key) {
461: int KC;
462: int t, rconpointer = 0;
463: int keyBits = key.length * 8;
464: byte[][] tk = new byte[4][MAXKC];
465: long[][] W = new long[MAXROUNDS + 1][4];
466:
467: switch (keyBits) {
468: case 128:
469: KC = 4;
470: break;
471: case 160:
472: KC = 5;
473: break;
474: case 192:
475: KC = 6;
476: break;
477: case 224:
478: KC = 7;
479: break;
480: case 256:
481: KC = 8;
482: break;
483: default:
484: throw new IllegalArgumentException(
485: "Key length not 128/160/192/224/256 bits.");
486: }
487:
488: if (keyBits >= blockBits) {
489: ROUNDS = KC + 6;
490: } else {
491: ROUNDS = (BC / 8) + 6;
492: }
493:
494: //
495: // copy the key into the processing area
496: //
497: int index = 0;
498:
499: for (int i = 0; i < key.length; i++) {
500: tk[i % 4][i / 4] = key[index++];
501: }
502:
503: t = 0;
504:
505: //
506: // copy values into round key array
507: //
508: for (int j = 0; (j < KC) && (t < (ROUNDS + 1) * (BC / 8)); j++, t++) {
509: for (int i = 0; i < 4; i++) {
510: W[t / (BC / 8)][i] |= (long) (tk[i][j] & 0xff) << ((t * 8) % BC);
511: }
512: }
513:
514: //
515: // while not enough round key material calculated
516: // calculate new values
517: //
518: while (t < (ROUNDS + 1) * (BC / 8)) {
519: for (int i = 0; i < 4; i++) {
520: tk[i][0] ^= S[tk[(i + 1) % 4][KC - 1] & 0xff];
521: }
522: tk[0][0] ^= rcon[rconpointer++];
523:
524: if (KC <= 6) {
525: for (int j = 1; j < KC; j++) {
526: for (int i = 0; i < 4; i++) {
527: tk[i][j] ^= tk[i][j - 1];
528: }
529: }
530: } else {
531: for (int j = 1; j < 4; j++) {
532: for (int i = 0; i < 4; i++) {
533: tk[i][j] ^= tk[i][j - 1];
534: }
535: }
536: for (int i = 0; i < 4; i++) {
537: tk[i][4] ^= S[tk[i][3] & 0xff];
538: }
539: for (int j = 5; j < KC; j++) {
540: for (int i = 0; i < 4; i++) {
541: tk[i][j] ^= tk[i][j - 1];
542: }
543: }
544: }
545:
546: //
547: // copy values into round key array
548: //
549: for (int j = 0; (j < KC) && (t < (ROUNDS + 1) * (BC / 8)); j++, t++) {
550: for (int i = 0; i < 4; i++) {
551: W[t / (BC / 8)][i] |= (long) (tk[i][j] & 0xff) << ((t * 8) % (BC));
552: }
553: }
554: }
555:
556: return W;
557: }
558:
559: private int BC;
560: private long BC_MASK;
561: private int ROUNDS;
562: private int blockBits;
563: private long[][] workingKey;
564: private long A0, A1, A2, A3;
565: private boolean forEncryption;
566: private byte[] shifts0SC;
567: private byte[] shifts1SC;
568:
569: /**
570: * default constructor - 128 bit block size.
571: */
572: public RijndaelEngine() {
573: this (128);
574: }
575:
576: /**
577: * basic constructor - set the cipher up for a given blocksize
578: *
579: * @param blockBits the blocksize in bits, must be 128, 192, or 256.
580: */
581: public RijndaelEngine(int blockBits) {
582: switch (blockBits) {
583: case 128:
584: BC = 32;
585: BC_MASK = 0xffffffffL;
586: shifts0SC = shifts0[0];
587: shifts1SC = shifts1[0];
588: break;
589: case 160:
590: BC = 40;
591: BC_MASK = 0xffffffffffL;
592: shifts0SC = shifts0[1];
593: shifts1SC = shifts1[1];
594: break;
595: case 192:
596: BC = 48;
597: BC_MASK = 0xffffffffffffL;
598: shifts0SC = shifts0[2];
599: shifts1SC = shifts1[2];
600: break;
601: case 224:
602: BC = 56;
603: BC_MASK = 0xffffffffffffffL;
604: shifts0SC = shifts0[3];
605: shifts1SC = shifts1[3];
606: break;
607: case 256:
608: BC = 64;
609: BC_MASK = 0xffffffffffffffffL;
610: shifts0SC = shifts0[4];
611: shifts1SC = shifts1[4];
612: break;
613: default:
614: throw new IllegalArgumentException(
615: "unknown blocksize to Rijndael");
616: }
617:
618: this .blockBits = blockBits;
619: }
620:
621: /**
622: * initialise a Rijndael cipher.
623: *
624: * @param forEncryption whether or not we are for encryption.
625: * @param params the parameters required to set up the cipher.
626: * @exception IllegalArgumentException if the params argument is
627: * inappropriate.
628: */
629: public void init(boolean forEncryption, CipherParameters params) {
630: if (params instanceof KeyParameter) {
631: workingKey = generateWorkingKey(((KeyParameter) params)
632: .getKey());
633: this .forEncryption = forEncryption;
634: return;
635: }
636:
637: throw new IllegalArgumentException(
638: "invalid parameter passed to Rijndael init - "
639: + params.getClass().getName());
640: }
641:
642: public String getAlgorithmName() {
643: return "Rijndael";
644: }
645:
646: public int getBlockSize() {
647: return BC / 2;
648: }
649:
650: public int processBlock(byte[] in, int inOff, byte[] out, int outOff) {
651: if (workingKey == null) {
652: throw new IllegalStateException(
653: "Rijndael engine not initialised");
654: }
655:
656: if ((inOff + (BC / 2)) > in.length) {
657: throw new DataLengthException("input buffer too short");
658: }
659:
660: if ((outOff + (BC / 2)) > out.length) {
661: throw new DataLengthException("output buffer too short");
662: }
663:
664: if (forEncryption) {
665: unpackBlock(in, inOff);
666: encryptBlock(workingKey);
667: packBlock(out, outOff);
668: } else {
669: unpackBlock(in, inOff);
670: decryptBlock(workingKey);
671: packBlock(out, outOff);
672: }
673:
674: return BC / 2;
675: }
676:
677: public void reset() {
678: }
679:
680: private final void unpackBlock(byte[] bytes, int off) {
681: int index = off;
682:
683: A0 = (bytes[index++] & 0xff);
684: A1 = (bytes[index++] & 0xff);
685: A2 = (bytes[index++] & 0xff);
686: A3 = (bytes[index++] & 0xff);
687:
688: for (int j = 8; j != BC; j += 8) {
689: A0 |= (long) (bytes[index++] & 0xff) << j;
690: A1 |= (long) (bytes[index++] & 0xff) << j;
691: A2 |= (long) (bytes[index++] & 0xff) << j;
692: A3 |= (long) (bytes[index++] & 0xff) << j;
693: }
694: }
695:
696: private final void packBlock(byte[] bytes, int off) {
697: int index = off;
698:
699: for (int j = 0; j != BC; j += 8) {
700: bytes[index++] = (byte) (A0 >> j);
701: bytes[index++] = (byte) (A1 >> j);
702: bytes[index++] = (byte) (A2 >> j);
703: bytes[index++] = (byte) (A3 >> j);
704: }
705: }
706:
707: private final void encryptBlock(long[][] rk) {
708: int r;
709:
710: //
711: // begin with a key addition
712: //
713: KeyAddition(rk[0]);
714:
715: //
716: // ROUNDS-1 ordinary rounds
717: //
718: for (r = 1; r < ROUNDS; r++) {
719: Substitution(S);
720: ShiftRow(shifts0SC);
721: MixColumn();
722: KeyAddition(rk[r]);
723: }
724:
725: //
726: // Last round is special: there is no MixColumn
727: //
728: Substitution(S);
729: ShiftRow(shifts0SC);
730: KeyAddition(rk[ROUNDS]);
731: }
732:
733: private final void decryptBlock(long[][] rk) {
734: int r;
735:
736: // To decrypt: apply the inverse operations of the encrypt routine,
737: // in opposite order
738: //
739: // (KeyAddition is an involution: it 's equal to its inverse)
740: // (the inverse of Substitution with table S is Substitution with the inverse table of S)
741: // (the inverse of Shiftrow is Shiftrow over a suitable distance)
742: //
743:
744: // First the special round:
745: // without InvMixColumn
746: // with extra KeyAddition
747: //
748: KeyAddition(rk[ROUNDS]);
749: Substitution(Si);
750: ShiftRow(shifts1SC);
751:
752: //
753: // ROUNDS-1 ordinary rounds
754: //
755: for (r = ROUNDS - 1; r > 0; r--) {
756: KeyAddition(rk[r]);
757: InvMixColumn();
758: Substitution(Si);
759: ShiftRow(shifts1SC);
760: }
761:
762: //
763: // End with the extra key addition
764: //
765: KeyAddition(rk[0]);
766: }
767: }
|