/src/BearSSL/src/symcipher/aes_ct.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org> |
3 | | * |
4 | | * Permission is hereby granted, free of charge, to any person obtaining |
5 | | * a copy of this software and associated documentation files (the |
6 | | * "Software"), to deal in the Software without restriction, including |
7 | | * without limitation the rights to use, copy, modify, merge, publish, |
8 | | * distribute, sublicense, and/or sell copies of the Software, and to |
9 | | * permit persons to whom the Software is furnished to do so, subject to |
10 | | * the following conditions: |
11 | | * |
12 | | * The above copyright notice and this permission notice shall be |
13 | | * included in all copies or substantial portions of the Software. |
14 | | * |
15 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
16 | | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
17 | | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
18 | | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
19 | | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
20 | | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
21 | | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
22 | | * SOFTWARE. |
23 | | */ |
24 | | |
25 | | #include "inner.h" |
26 | | |
27 | | /* see inner.h */ |
28 | | void |
29 | | br_aes_ct_bitslice_Sbox(uint32_t *q) |
30 | 473k | { |
31 | | /* |
32 | | * This S-box implementation is a straightforward translation of |
33 | | * the circuit described by Boyar and Peralta in "A new |
34 | | * combinational logic minimization technique with applications |
35 | | * to cryptology" (https://eprint.iacr.org/2009/191.pdf). |
36 | | * |
37 | | * Note that variables x* (input) and s* (output) are numbered |
38 | | * in "reverse" order (x0 is the high bit, x7 is the low bit). |
39 | | */ |
40 | | |
41 | 473k | uint32_t x0, x1, x2, x3, x4, x5, x6, x7; |
42 | 473k | uint32_t y1, y2, y3, y4, y5, y6, y7, y8, y9; |
43 | 473k | uint32_t y10, y11, y12, y13, y14, y15, y16, y17, y18, y19; |
44 | 473k | uint32_t y20, y21; |
45 | 473k | uint32_t z0, z1, z2, z3, z4, z5, z6, z7, z8, z9; |
46 | 473k | uint32_t z10, z11, z12, z13, z14, z15, z16, z17; |
47 | 473k | uint32_t t0, t1, t2, t3, t4, t5, t6, t7, t8, t9; |
48 | 473k | uint32_t t10, t11, t12, t13, t14, t15, t16, t17, t18, t19; |
49 | 473k | uint32_t t20, t21, t22, t23, t24, t25, t26, t27, t28, t29; |
50 | 473k | uint32_t t30, t31, t32, t33, t34, t35, t36, t37, t38, t39; |
51 | 473k | uint32_t t40, t41, t42, t43, t44, t45, t46, t47, t48, t49; |
52 | 473k | uint32_t t50, t51, t52, t53, t54, t55, t56, t57, t58, t59; |
53 | 473k | uint32_t t60, t61, t62, t63, t64, t65, t66, t67; |
54 | 473k | uint32_t s0, s1, s2, s3, s4, s5, s6, s7; |
55 | | |
56 | 473k | x0 = q[7]; |
57 | 473k | x1 = q[6]; |
58 | 473k | x2 = q[5]; |
59 | 473k | x3 = q[4]; |
60 | 473k | x4 = q[3]; |
61 | 473k | x5 = q[2]; |
62 | 473k | x6 = q[1]; |
63 | 473k | x7 = q[0]; |
64 | | |
65 | | /* |
66 | | * Top linear transformation. |
67 | | */ |
68 | 473k | y14 = x3 ^ x5; |
69 | 473k | y13 = x0 ^ x6; |
70 | 473k | y9 = x0 ^ x3; |
71 | 473k | y8 = x0 ^ x5; |
72 | 473k | t0 = x1 ^ x2; |
73 | 473k | y1 = t0 ^ x7; |
74 | 473k | y4 = y1 ^ x3; |
75 | 473k | y12 = y13 ^ y14; |
76 | 473k | y2 = y1 ^ x0; |
77 | 473k | y5 = y1 ^ x6; |
78 | 473k | y3 = y5 ^ y8; |
79 | 473k | t1 = x4 ^ y12; |
80 | 473k | y15 = t1 ^ x5; |
81 | 473k | y20 = t1 ^ x1; |
82 | 473k | y6 = y15 ^ x7; |
83 | 473k | y10 = y15 ^ t0; |
84 | 473k | y11 = y20 ^ y9; |
85 | 473k | y7 = x7 ^ y11; |
86 | 473k | y17 = y10 ^ y11; |
87 | 473k | y19 = y10 ^ y8; |
88 | 473k | y16 = t0 ^ y11; |
89 | 473k | y21 = y13 ^ y16; |
90 | 473k | y18 = x0 ^ y16; |
91 | | |
92 | | /* |
93 | | * Non-linear section. |
94 | | */ |
95 | 473k | t2 = y12 & y15; |
96 | 473k | t3 = y3 & y6; |
97 | 473k | t4 = t3 ^ t2; |
98 | 473k | t5 = y4 & x7; |
99 | 473k | t6 = t5 ^ t2; |
100 | 473k | t7 = y13 & y16; |
101 | 473k | t8 = y5 & y1; |
102 | 473k | t9 = t8 ^ t7; |
103 | 473k | t10 = y2 & y7; |
104 | 473k | t11 = t10 ^ t7; |
105 | 473k | t12 = y9 & y11; |
106 | 473k | t13 = y14 & y17; |
107 | 473k | t14 = t13 ^ t12; |
108 | 473k | t15 = y8 & y10; |
109 | 473k | t16 = t15 ^ t12; |
110 | 473k | t17 = t4 ^ t14; |
111 | 473k | t18 = t6 ^ t16; |
112 | 473k | t19 = t9 ^ t14; |
113 | 473k | t20 = t11 ^ t16; |
114 | 473k | t21 = t17 ^ y20; |
115 | 473k | t22 = t18 ^ y19; |
116 | 473k | t23 = t19 ^ y21; |
117 | 473k | t24 = t20 ^ y18; |
118 | | |
119 | 473k | t25 = t21 ^ t22; |
120 | 473k | t26 = t21 & t23; |
121 | 473k | t27 = t24 ^ t26; |
122 | 473k | t28 = t25 & t27; |
123 | 473k | t29 = t28 ^ t22; |
124 | 473k | t30 = t23 ^ t24; |
125 | 473k | t31 = t22 ^ t26; |
126 | 473k | t32 = t31 & t30; |
127 | 473k | t33 = t32 ^ t24; |
128 | 473k | t34 = t23 ^ t33; |
129 | 473k | t35 = t27 ^ t33; |
130 | 473k | t36 = t24 & t35; |
131 | 473k | t37 = t36 ^ t34; |
132 | 473k | t38 = t27 ^ t36; |
133 | 473k | t39 = t29 & t38; |
134 | 473k | t40 = t25 ^ t39; |
135 | | |
136 | 473k | t41 = t40 ^ t37; |
137 | 473k | t42 = t29 ^ t33; |
138 | 473k | t43 = t29 ^ t40; |
139 | 473k | t44 = t33 ^ t37; |
140 | 473k | t45 = t42 ^ t41; |
141 | 473k | z0 = t44 & y15; |
142 | 473k | z1 = t37 & y6; |
143 | 473k | z2 = t33 & x7; |
144 | 473k | z3 = t43 & y16; |
145 | 473k | z4 = t40 & y1; |
146 | 473k | z5 = t29 & y7; |
147 | 473k | z6 = t42 & y11; |
148 | 473k | z7 = t45 & y17; |
149 | 473k | z8 = t41 & y10; |
150 | 473k | z9 = t44 & y12; |
151 | 473k | z10 = t37 & y3; |
152 | 473k | z11 = t33 & y4; |
153 | 473k | z12 = t43 & y13; |
154 | 473k | z13 = t40 & y5; |
155 | 473k | z14 = t29 & y2; |
156 | 473k | z15 = t42 & y9; |
157 | 473k | z16 = t45 & y14; |
158 | 473k | z17 = t41 & y8; |
159 | | |
160 | | /* |
161 | | * Bottom linear transformation. |
162 | | */ |
163 | 473k | t46 = z15 ^ z16; |
164 | 473k | t47 = z10 ^ z11; |
165 | 473k | t48 = z5 ^ z13; |
166 | 473k | t49 = z9 ^ z10; |
167 | 473k | t50 = z2 ^ z12; |
168 | 473k | t51 = z2 ^ z5; |
169 | 473k | t52 = z7 ^ z8; |
170 | 473k | t53 = z0 ^ z3; |
171 | 473k | t54 = z6 ^ z7; |
172 | 473k | t55 = z16 ^ z17; |
173 | 473k | t56 = z12 ^ t48; |
174 | 473k | t57 = t50 ^ t53; |
175 | 473k | t58 = z4 ^ t46; |
176 | 473k | t59 = z3 ^ t54; |
177 | 473k | t60 = t46 ^ t57; |
178 | 473k | t61 = z14 ^ t57; |
179 | 473k | t62 = t52 ^ t58; |
180 | 473k | t63 = t49 ^ t58; |
181 | 473k | t64 = z4 ^ t59; |
182 | 473k | t65 = t61 ^ t62; |
183 | 473k | t66 = z1 ^ t63; |
184 | 473k | s0 = t59 ^ t63; |
185 | 473k | s6 = t56 ^ ~t62; |
186 | 473k | s7 = t48 ^ ~t60; |
187 | 473k | t67 = t64 ^ t65; |
188 | 473k | s3 = t53 ^ t66; |
189 | 473k | s4 = t51 ^ t66; |
190 | 473k | s5 = t47 ^ t65; |
191 | 473k | s1 = t64 ^ ~s3; |
192 | 473k | s2 = t55 ^ ~t67; |
193 | | |
194 | 473k | q[7] = s0; |
195 | 473k | q[6] = s1; |
196 | 473k | q[5] = s2; |
197 | 473k | q[4] = s3; |
198 | 473k | q[3] = s4; |
199 | 473k | q[2] = s5; |
200 | 473k | q[1] = s6; |
201 | 473k | q[0] = s7; |
202 | 473k | } |
203 | | |
204 | | /* see inner.h */ |
205 | | void |
206 | | br_aes_ct_ortho(uint32_t *q) |
207 | 139k | { |
208 | 1.67M | #define SWAPN(cl, ch, s, x, y) do { \ |
209 | 1.67M | uint32_t a, b; \ |
210 | 1.67M | a = (x); \ |
211 | 1.67M | b = (y); \ |
212 | 1.67M | (x) = (a & (uint32_t)cl) | ((b & (uint32_t)cl) << (s)); \ |
213 | 1.67M | (y) = ((a & (uint32_t)ch) >> (s)) | (b & (uint32_t)ch); \ |
214 | 1.67M | } while (0) |
215 | | |
216 | 558k | #define SWAP2(x, y) SWAPN(0x55555555, 0xAAAAAAAA, 1, x, y) |
217 | 558k | #define SWAP4(x, y) SWAPN(0x33333333, 0xCCCCCCCC, 2, x, y) |
218 | 558k | #define SWAP8(x, y) SWAPN(0x0F0F0F0F, 0xF0F0F0F0, 4, x, y) |
219 | | |
220 | 139k | SWAP2(q[0], q[1]); |
221 | 139k | SWAP2(q[2], q[3]); |
222 | 139k | SWAP2(q[4], q[5]); |
223 | 139k | SWAP2(q[6], q[7]); |
224 | | |
225 | 139k | SWAP4(q[0], q[2]); |
226 | 139k | SWAP4(q[1], q[3]); |
227 | 139k | SWAP4(q[4], q[6]); |
228 | 139k | SWAP4(q[5], q[7]); |
229 | | |
230 | 139k | SWAP8(q[0], q[4]); |
231 | 139k | SWAP8(q[1], q[5]); |
232 | 139k | SWAP8(q[2], q[6]); |
233 | 139k | SWAP8(q[3], q[7]); |
234 | 139k | } |
235 | | |
236 | | static const unsigned char Rcon[] = { |
237 | | 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 |
238 | | }; |
239 | | |
240 | | static uint32_t |
241 | | sub_word(uint32_t x) |
242 | 19.5k | { |
243 | 19.5k | uint32_t q[8]; |
244 | 19.5k | int i; |
245 | | |
246 | 176k | for (i = 0; i < 8; i ++) { |
247 | 156k | q[i] = x; |
248 | 156k | } |
249 | 19.5k | br_aes_ct_ortho(q); |
250 | 19.5k | br_aes_ct_bitslice_Sbox(q); |
251 | 19.5k | br_aes_ct_ortho(q); |
252 | 19.5k | return q[0]; |
253 | 19.5k | } |
254 | | |
255 | | /* see inner.h */ |
256 | | unsigned |
257 | | br_aes_ct_keysched(uint32_t *comp_skey, const void *key, size_t key_len) |
258 | 1.91k | { |
259 | 1.91k | unsigned num_rounds; |
260 | 1.91k | int i, j, k, nk, nkf; |
261 | 1.91k | uint32_t tmp; |
262 | 1.91k | uint32_t skey[120]; |
263 | | |
264 | 1.91k | switch (key_len) { |
265 | 1.21k | case 16: |
266 | 1.21k | num_rounds = 10; |
267 | 1.21k | break; |
268 | 339 | case 24: |
269 | 339 | num_rounds = 12; |
270 | 339 | break; |
271 | 364 | case 32: |
272 | 364 | num_rounds = 14; |
273 | 364 | break; |
274 | 0 | default: |
275 | | /* abort(); */ |
276 | 0 | return 0; |
277 | 1.91k | } |
278 | 1.91k | nk = (int)(key_len >> 2); |
279 | 1.91k | nkf = (int)((num_rounds + 1) << 2); |
280 | 1.91k | tmp = 0; |
281 | 11.7k | for (i = 0; i < nk; i ++) { |
282 | 9.80k | tmp = br_dec32le((const unsigned char *)key + (i << 2)); |
283 | 9.80k | skey[(i << 1) + 0] = tmp; |
284 | 9.80k | skey[(i << 1) + 1] = tmp; |
285 | 9.80k | } |
286 | 85.0k | for (i = nk, j = 0, k = 0; i < nkf; i ++) { |
287 | 83.1k | if (j == 0) { |
288 | 17.4k | tmp = (tmp << 24) | (tmp >> 8); |
289 | 17.4k | tmp = sub_word(tmp) ^ Rcon[k]; |
290 | 65.7k | } else if (nk > 6 && j == 4) { |
291 | 2.18k | tmp = sub_word(tmp); |
292 | 2.18k | } |
293 | 83.1k | tmp ^= skey[(i - nk) << 1]; |
294 | 83.1k | skey[(i << 1) + 0] = tmp; |
295 | 83.1k | skey[(i << 1) + 1] = tmp; |
296 | 83.1k | if (++ j == nk) { |
297 | 16.7k | j = 0; |
298 | 16.7k | k ++; |
299 | 16.7k | } |
300 | 83.1k | } |
301 | 25.1k | for (i = 0; i < nkf; i += 4) { |
302 | 23.2k | br_aes_ct_ortho(skey + (i << 1)); |
303 | 23.2k | } |
304 | 94.8k | for (i = 0, j = 0; i < nkf; i ++, j += 2) { |
305 | 92.9k | comp_skey[i] = (skey[j + 0] & 0x55555555) |
306 | 92.9k | | (skey[j + 1] & 0xAAAAAAAA); |
307 | 92.9k | } |
308 | 1.91k | return num_rounds; |
309 | 1.91k | } |
310 | | |
311 | | /* see inner.h */ |
312 | | void |
313 | | br_aes_ct_skey_expand(uint32_t *skey, |
314 | | unsigned num_rounds, const uint32_t *comp_skey) |
315 | 13.9k | { |
316 | 13.9k | unsigned u, v, n; |
317 | | |
318 | 13.9k | n = (num_rounds + 1) << 2; |
319 | 678k | for (u = 0, v = 0; u < n; u ++, v += 2) { |
320 | 664k | uint32_t x, y; |
321 | | |
322 | 664k | x = y = comp_skey[u]; |
323 | 664k | x &= 0x55555555; |
324 | 664k | skey[v + 0] = x | (x << 1); |
325 | 664k | y &= 0xAAAAAAAA; |
326 | 664k | skey[v + 1] = y | (y >> 1); |
327 | 664k | } |
328 | 13.9k | } |