[DELAYIMP] Fix 2 Clang-Cl warnings about __pfnDliNotifyHook2Default and __pfnDliFailu...
[reactos.git] / sdk / lib / cryptlib / mvAesAlg.c
1 /* rijndael-alg-ref.c v2.0 August '99
2 * Reference ANSI C code
3 * authors: Paulo Barreto
4 * Vincent Rijmen, K.U.Leuven
5 *
6 * This code is placed in the public domain.
7 */
8
9 #include "mvOs.h"
10
11 #include "mvAesAlg.h"
12
13 #include "mvAesBoxes.dat"
14
15
16 MV_U8 mul1(MV_U8 aa, MV_U8 bb);
17 void KeyAddition(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC], MV_U8 BC);
18 void ShiftRow128Enc(MV_U8 a[4][MAXBC]);
19 void ShiftRow128Dec(MV_U8 a[4][MAXBC]);
20 void Substitution(MV_U8 a[4][MAXBC], MV_U8 box[256]);
21 void MixColumn(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC]);
22 void InvMixColumn(MV_U8 a[4][MAXBC]);
23
24
25 #define mul(aa, bb) (mask[bb] & Alogtable[aa + Logtable[bb]])
26
27 MV_U8 mul1(MV_U8 aa, MV_U8 bb)
28 {
29 return mask[bb] & Alogtable[aa + Logtable[bb]];
30 }
31
32
33 void KeyAddition(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC], MV_U8 BC)
34 {
35 /* Exor corresponding text input and round key input bytes
36 */
37 ((MV_U32*)(&(a[0][0])))[0] ^= ((MV_U32*)(&(rk[0][0])))[0];
38 ((MV_U32*)(&(a[1][0])))[0] ^= ((MV_U32*)(&(rk[1][0])))[0];
39 ((MV_U32*)(&(a[2][0])))[0] ^= ((MV_U32*)(&(rk[2][0])))[0];
40 ((MV_U32*)(&(a[3][0])))[0] ^= ((MV_U32*)(&(rk[3][0])))[0];
41
42 }
43
44 void ShiftRow128Enc(MV_U8 a[4][MAXBC]) {
45 /* Row 0 remains unchanged
46 * The other three rows are shifted a variable amount
47 */
48 MV_U8 tmp[MAXBC];
49
50 tmp[0] = a[1][1];
51 tmp[1] = a[1][2];
52 tmp[2] = a[1][3];
53 tmp[3] = a[1][0];
54
55 ((MV_U32*)(&(a[1][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
56 /*
57 a[1][0] = tmp[0];
58 a[1][1] = tmp[1];
59 a[1][2] = tmp[2];
60 a[1][3] = tmp[3];
61 */
62 tmp[0] = a[2][2];
63 tmp[1] = a[2][3];
64 tmp[2] = a[2][0];
65 tmp[3] = a[2][1];
66
67 ((MV_U32*)(&(a[2][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
68 /*
69 a[2][0] = tmp[0];
70 a[2][1] = tmp[1];
71 a[2][2] = tmp[2];
72 a[2][3] = tmp[3];
73 */
74 tmp[0] = a[3][3];
75 tmp[1] = a[3][0];
76 tmp[2] = a[3][1];
77 tmp[3] = a[3][2];
78
79 ((MV_U32*)(&(a[3][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
80 /*
81 a[3][0] = tmp[0];
82 a[3][1] = tmp[1];
83 a[3][2] = tmp[2];
84 a[3][3] = tmp[3];
85 */
86 }
87
88 void ShiftRow128Dec(MV_U8 a[4][MAXBC]) {
89 /* Row 0 remains unchanged
90 * The other three rows are shifted a variable amount
91 */
92 MV_U8 tmp[MAXBC];
93
94 tmp[0] = a[1][3];
95 tmp[1] = a[1][0];
96 tmp[2] = a[1][1];
97 tmp[3] = a[1][2];
98
99 ((MV_U32*)(&(a[1][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
100 /*
101 a[1][0] = tmp[0];
102 a[1][1] = tmp[1];
103 a[1][2] = tmp[2];
104 a[1][3] = tmp[3];
105 */
106
107 tmp[0] = a[2][2];
108 tmp[1] = a[2][3];
109 tmp[2] = a[2][0];
110 tmp[3] = a[2][1];
111
112 ((MV_U32*)(&(a[2][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
113 /*
114 a[2][0] = tmp[0];
115 a[2][1] = tmp[1];
116 a[2][2] = tmp[2];
117 a[2][3] = tmp[3];
118 */
119
120 tmp[0] = a[3][1];
121 tmp[1] = a[3][2];
122 tmp[2] = a[3][3];
123 tmp[3] = a[3][0];
124
125 ((MV_U32*)(&(a[3][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
126 /*
127 a[3][0] = tmp[0];
128 a[3][1] = tmp[1];
129 a[3][2] = tmp[2];
130 a[3][3] = tmp[3];
131 */
132 }
133
134 void Substitution(MV_U8 a[4][MAXBC], MV_U8 box[256]) {
135 /* Replace every byte of the input by the byte at that place
136 * in the nonlinear S-box
137 */
138 int i, j;
139
140 for(i = 0; i < 4; i++)
141 for(j = 0; j < 4; j++) a[i][j] = box[a[i][j]] ;
142 }
143
144 void MixColumn(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC]) {
145 /* Mix the four bytes of every column in a linear way
146 */
147 MV_U8 b[4][MAXBC];
148 int i, j;
149
150 for(j = 0; j < 4; j++){
151 b[0][j] = mul(25,a[0][j]) ^ mul(1,a[1][j]) ^ a[2][j] ^ a[3][j];
152 b[1][j] = mul(25,a[1][j]) ^ mul(1,a[2][j]) ^ a[3][j] ^ a[0][j];
153 b[2][j] = mul(25,a[2][j]) ^ mul(1,a[3][j]) ^ a[0][j] ^ a[1][j];
154 b[3][j] = mul(25,a[3][j]) ^ mul(1,a[0][j]) ^ a[1][j] ^ a[2][j];
155 }
156 for(i = 0; i < 4; i++)
157 /*for(j = 0; j < BC; j++) a[i][j] = b[i][j];*/
158 ((MV_U32*)(&(a[i][0])))[0] = ((MV_U32*)(&(b[i][0])))[0] ^ ((MV_U32*)(&(rk[i][0])))[0];
159 }
160
161 void InvMixColumn(MV_U8 a[4][MAXBC]) {
162 /* Mix the four bytes of every column in a linear way
163 * This is the opposite operation of Mixcolumn
164 */
165 MV_U8 b[4][MAXBC];
166 int i, j;
167
168 for(j = 0; j < 4; j++){
169 b[0][j] = mul(223,a[0][j]) ^ mul(104,a[1][j]) ^ mul(238,a[2][j]) ^ mul(199,a[3][j]);
170 b[1][j] = mul(223,a[1][j]) ^ mul(104,a[2][j]) ^ mul(238,a[3][j]) ^ mul(199,a[0][j]);
171 b[2][j] = mul(223,a[2][j]) ^ mul(104,a[3][j]) ^ mul(238,a[0][j]) ^ mul(199,a[1][j]);
172 b[3][j] = mul(223,a[3][j]) ^ mul(104,a[0][j]) ^ mul(238,a[1][j]) ^ mul(199,a[2][j]);
173 }
174 for(i = 0; i < 4; i++)
175 /*for(j = 0; j < BC; j++) a[i][j] = b[i][j];*/
176 ((MV_U32*)(&(a[i][0])))[0] = ((MV_U32*)(&(b[i][0])))[0];
177 }
178
179 int rijndaelKeySched (MV_U8 k[4][MAXKC], int keyBits, int blockBits, MV_U8 W[MAXROUNDS+1][4][MAXBC])
180 {
181 /* Calculate the necessary round keys
182 * The number of calculations depends on keyBits and blockBits
183 */
184 int KC, BC, ROUNDS;
185 int i, j, t, rconpointer = 0;
186 MV_U8 tk[4][MAXKC];
187
188 switch (keyBits) {
189 case 128: KC = 4; break;
190 case 192: KC = 6; break;
191 case 256: KC = 8; break;
192 default : return (-1);
193 }
194
195 switch (blockBits) {
196 case 128: BC = 4; break;
197 case 192: BC = 6; break;
198 case 256: BC = 8; break;
199 default : return (-2);
200 }
201
202 switch (keyBits >= blockBits ? keyBits : blockBits) {
203 case 128: ROUNDS = 10; break;
204 case 192: ROUNDS = 12; break;
205 case 256: ROUNDS = 14; break;
206 default : return (-3); /* this cannot happen */
207 }
208
209
210 for(j = 0; j < KC; j++)
211 for(i = 0; i < 4; i++)
212 tk[i][j] = k[i][j];
213 t = 0;
214 /* copy values into round key array */
215 for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
216 for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
217
218 while (t < (ROUNDS+1)*BC) { /* while not enough round key material calculated */
219 /* calculate new values */
220 for(i = 0; i < 4; i++)
221 tk[i][0] ^= S[tk[(i+1)%4][KC-1]];
222 tk[0][0] ^= rcon[rconpointer++];
223
224 if (KC != 8)
225 for(j = 1; j < KC; j++)
226 for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
227 else {
228 for(j = 1; j < KC/2; j++)
229 for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
230 for(i = 0; i < 4; i++) tk[i][KC/2] ^= S[tk[i][KC/2 - 1]];
231 for(j = KC/2 + 1; j < KC; j++)
232 for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
233 }
234 /* copy values into round key array */
235 for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
236 for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
237 }
238
239 return 0;
240 }
241
242
243
244 int rijndaelEncrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds)
245 {
246 /* Encryption of one block.
247 */
248 int r, BC, ROUNDS;
249
250 BC = 4;
251 ROUNDS = rounds;
252
253 /* begin with a key addition
254 */
255
256 KeyAddition(a,rk[0],BC);
257
258 /* ROUNDS-1 ordinary rounds
259 */
260 for(r = 1; r < ROUNDS; r++) {
261 Substitution(a,S);
262 ShiftRow128Enc(a);
263 MixColumn(a, rk[r]);
264 /*KeyAddition(a,rk[r],BC);*/
265 }
266
267 /* Last round is special: there is no MixColumn
268 */
269 Substitution(a,S);
270 ShiftRow128Enc(a);
271 KeyAddition(a,rk[ROUNDS],BC);
272
273 return 0;
274 }
275
276
277 int rijndaelDecrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds)
278 {
279 int r, BC, ROUNDS;
280
281 BC = 4;
282 ROUNDS = rounds;
283
284 /* To decrypt: apply the inverse operations of the encrypt routine,
285 * in opposite order
286 *
287 * (KeyAddition is an involution: it 's equal to its inverse)
288 * (the inverse of Substitution with table S is Substitution with the inverse table of S)
289 * (the inverse of Shiftrow is Shiftrow over a suitable distance)
290 */
291
292 /* First the special round:
293 * without InvMixColumn
294 * with extra KeyAddition
295 */
296 KeyAddition(a,rk[ROUNDS],BC);
297 ShiftRow128Dec(a);
298 Substitution(a,Si);
299
300 /* ROUNDS-1 ordinary rounds
301 */
302 for(r = ROUNDS-1; r > 0; r--) {
303 KeyAddition(a,rk[r],BC);
304 InvMixColumn(a);
305 ShiftRow128Dec(a);
306 Substitution(a,Si);
307
308 }
309
310 /* End with the extra key addition
311 */
312
313 KeyAddition(a,rk[0],BC);
314
315 return 0;
316 }
317