• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 5079590438

25 May 2023 12:28PM UTC coverage: 92.228% (+0.5%) from 91.723%
5079590438

Pull #3502

github

Pull Request #3502: Apply clang-format to the codebase

75589 of 81959 relevant lines covered (92.23%)

12139530.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.75
/src/lib/block/aes/aes.cpp
1
/*
2
* (C) 1999-2010,2015,2017,2018,2020 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6

7
#include <botan/internal/aes.h>
8

9
#include <botan/internal/bit_ops.h>
10
#include <botan/internal/cpuid.h>
11
#include <botan/internal/ct_utils.h>
12
#include <botan/internal/loadstor.h>
13
#include <botan/internal/rotate.h>
14

15
namespace Botan {
16

17
#if defined(BOTAN_HAS_AES_POWER8) || defined(BOTAN_HAS_AES_ARMV8) || defined(BOTAN_HAS_AES_NI)
18
   #define BOTAN_HAS_HW_AES_SUPPORT
19
#endif
20

21
/*
22
* One of three AES implementation strategies are used to get a constant time
23
* implementation which is immune to common cache/timing based side channels:
24
*
25
* - If AES hardware support is available (AES-NI, POWER8, Aarch64) use that
26
*
27
* - If 128-bit SIMD with byte shuffles are available (SSSE3, NEON, or Altivec),
28
*   use the vperm technique published by Mike Hamburg at CHES 2009.
29
*
30
* - If no hardware or SIMD support, fall back to a constant time bitsliced
31
*   implementation. This uses 32-bit words resulting in 2 blocks being processed
32
*   in parallel. Moving to 4 blocks (with 64-bit words) would approximately
33
*   double performance on 64-bit CPUs. Likewise moving to 128 bit SIMD would
34
*   again approximately double performance vs 64-bit. However the assumption is
35
*   that most 64-bit CPUs either have hardware AES or SIMD shuffle support and
36
*   that the majority of users falling back to this code will be 32-bit cores.
37
*   If this assumption proves to be unsound, the bitsliced code can easily be
38
*   extended to operate on either 32 or 64 bit words depending on the native
39
*   wordsize of the target processor.
40
*
41
* Useful references
42
*
43
* - "Accelerating AES with Vector Permute Instructions" Mike Hamburg
44
*   https://www.shiftleft.org/papers/vector_aes/vector_aes.pdf
45
*
46
* - "Faster and Timing-Attack Resistant AES-GCM" Käsper and Schwabe
47
*   https://eprint.iacr.org/2009/129.pdf
48
*
49
* - "A new combinational logic minimization technique with applications to cryptology."
50
*   Boyar and Peralta https://eprint.iacr.org/2009/191.pdf
51
*
52
* - "A depth-16 circuit for the AES S-box" Boyar and Peralta
53
*    https://eprint.iacr.org/2011/332.pdf
54
*
55
* - "A Very Compact S-box for AES" Canright
56
*   https://www.iacr.org/archive/ches2005/032.pdf
57
*   https://core.ac.uk/download/pdf/36694529.pdf (extended)
58
*/
59

60
namespace {
61

62
/*
63
This is an AES sbox circuit which can execute in bitsliced mode up to 32x in
64
parallel.
65

66
The circuit is from the "Circuit Minimization Team" group
67
http://www.cs.yale.edu/homes/peralta/CircuitStuff/CMT.html
68
http://www.cs.yale.edu/homes/peralta/CircuitStuff/SLP_AES_113.txt
69

70
This circuit has size 113 and depth 27. In software it is much faster than
71
circuits which are considered faster for hardware purposes (where circuit depth
72
is the critical constraint), because unlike in hardware, on common CPUs we can
73
only execute - at best - 3 or 4 logic operations per cycle. So a smaller circuit
74
is superior. On an x86-64 machine this circuit is about 15% faster than the
75
circuit of size 128 and depth 16 given in "A depth-16 circuit for the AES S-box".
76

77
Another circuit for AES Sbox of size 102 and depth 24 is describted in "New
78
Circuit Minimization Techniques for Smaller and Faster AES SBoxes"
79
[https://eprint.iacr.org/2019/802] however it relies on "non-standard" gates
80
like MUX, NOR, NAND, etc and so in practice in bitsliced software, its size is
81
actually a bit larger than this circuit, as few CPUs have such instructions and
82
otherwise they must be emulated using a sequence of available bit operations.
83
*/
84
void AES_SBOX(uint32_t V[8]) {
129,812✔
85
   const uint32_t U0 = V[0];
129,812✔
86
   const uint32_t U1 = V[1];
129,812✔
87
   const uint32_t U2 = V[2];
129,812✔
88
   const uint32_t U3 = V[3];
129,812✔
89
   const uint32_t U4 = V[4];
129,812✔
90
   const uint32_t U5 = V[5];
129,812✔
91
   const uint32_t U6 = V[6];
129,812✔
92
   const uint32_t U7 = V[7];
129,812✔
93

94
   const uint32_t y14 = U3 ^ U5;
129,812✔
95
   const uint32_t y13 = U0 ^ U6;
129,812✔
96
   const uint32_t y9 = U0 ^ U3;
129,812✔
97
   const uint32_t y8 = U0 ^ U5;
129,812✔
98
   const uint32_t t0 = U1 ^ U2;
129,812✔
99
   const uint32_t y1 = t0 ^ U7;
129,812✔
100
   const uint32_t y4 = y1 ^ U3;
129,812✔
101
   const uint32_t y12 = y13 ^ y14;
129,812✔
102
   const uint32_t y2 = y1 ^ U0;
129,812✔
103
   const uint32_t y5 = y1 ^ U6;
129,812✔
104
   const uint32_t y3 = y5 ^ y8;
129,812✔
105
   const uint32_t t1 = U4 ^ y12;
129,812✔
106
   const uint32_t y15 = t1 ^ U5;
129,812✔
107
   const uint32_t y20 = t1 ^ U1;
129,812✔
108
   const uint32_t y6 = y15 ^ U7;
129,812✔
109
   const uint32_t y10 = y15 ^ t0;
129,812✔
110
   const uint32_t y11 = y20 ^ y9;
129,812✔
111
   const uint32_t y7 = U7 ^ y11;
129,812✔
112
   const uint32_t y17 = y10 ^ y11;
129,812✔
113
   const uint32_t y19 = y10 ^ y8;
129,812✔
114
   const uint32_t y16 = t0 ^ y11;
129,812✔
115
   const uint32_t y21 = y13 ^ y16;
129,812✔
116
   const uint32_t y18 = U0 ^ y16;
129,812✔
117
   const uint32_t t2 = y12 & y15;
129,812✔
118
   const uint32_t t3 = y3 & y6;
129,812✔
119
   const uint32_t t4 = t3 ^ t2;
129,812✔
120
   const uint32_t t5 = y4 & U7;
129,812✔
121
   const uint32_t t6 = t5 ^ t2;
129,812✔
122
   const uint32_t t7 = y13 & y16;
129,812✔
123
   const uint32_t t8 = y5 & y1;
129,812✔
124
   const uint32_t t9 = t8 ^ t7;
129,812✔
125
   const uint32_t t10 = y2 & y7;
129,812✔
126
   const uint32_t t11 = t10 ^ t7;
129,812✔
127
   const uint32_t t12 = y9 & y11;
129,812✔
128
   const uint32_t t13 = y14 & y17;
129,812✔
129
   const uint32_t t14 = t13 ^ t12;
129,812✔
130
   const uint32_t t15 = y8 & y10;
129,812✔
131
   const uint32_t t16 = t15 ^ t12;
129,812✔
132
   const uint32_t t17 = t4 ^ y20;
129,812✔
133
   const uint32_t t18 = t6 ^ t16;
129,812✔
134
   const uint32_t t19 = t9 ^ t14;
129,812✔
135
   const uint32_t t20 = t11 ^ t16;
129,812✔
136
   const uint32_t t21 = t17 ^ t14;
129,812✔
137
   const uint32_t t22 = t18 ^ y19;
129,812✔
138
   const uint32_t t23 = t19 ^ y21;
129,812✔
139
   const uint32_t t24 = t20 ^ y18;
129,812✔
140
   const uint32_t t25 = t21 ^ t22;
129,812✔
141
   const uint32_t t26 = t21 & t23;
129,812✔
142
   const uint32_t t27 = t24 ^ t26;
129,812✔
143
   const uint32_t t28 = t25 & t27;
129,812✔
144
   const uint32_t t29 = t28 ^ t22;
129,812✔
145
   const uint32_t t30 = t23 ^ t24;
129,812✔
146
   const uint32_t t31 = t22 ^ t26;
129,812✔
147
   const uint32_t t32 = t31 & t30;
129,812✔
148
   const uint32_t t33 = t32 ^ t24;
129,812✔
149
   const uint32_t t34 = t23 ^ t33;
129,812✔
150
   const uint32_t t35 = t27 ^ t33;
129,812✔
151
   const uint32_t t36 = t24 & t35;
129,812✔
152
   const uint32_t t37 = t36 ^ t34;
129,812✔
153
   const uint32_t t38 = t27 ^ t36;
129,812✔
154
   const uint32_t t39 = t29 & t38;
129,812✔
155
   const uint32_t t40 = t25 ^ t39;
129,812✔
156
   const uint32_t t41 = t40 ^ t37;
129,812✔
157
   const uint32_t t42 = t29 ^ t33;
129,812✔
158
   const uint32_t t43 = t29 ^ t40;
129,812✔
159
   const uint32_t t44 = t33 ^ t37;
129,812✔
160
   const uint32_t t45 = t42 ^ t41;
129,812✔
161
   const uint32_t z0 = t44 & y15;
129,812✔
162
   const uint32_t z1 = t37 & y6;
129,812✔
163
   const uint32_t z2 = t33 & U7;
129,812✔
164
   const uint32_t z3 = t43 & y16;
129,812✔
165
   const uint32_t z4 = t40 & y1;
129,812✔
166
   const uint32_t z5 = t29 & y7;
129,812✔
167
   const uint32_t z6 = t42 & y11;
129,812✔
168
   const uint32_t z7 = t45 & y17;
129,812✔
169
   const uint32_t z8 = t41 & y10;
129,812✔
170
   const uint32_t z9 = t44 & y12;
129,812✔
171
   const uint32_t z10 = t37 & y3;
129,812✔
172
   const uint32_t z11 = t33 & y4;
129,812✔
173
   const uint32_t z12 = t43 & y13;
129,812✔
174
   const uint32_t z13 = t40 & y5;
129,812✔
175
   const uint32_t z14 = t29 & y2;
129,812✔
176
   const uint32_t z15 = t42 & y9;
129,812✔
177
   const uint32_t z16 = t45 & y14;
129,812✔
178
   const uint32_t z17 = t41 & y8;
129,812✔
179
   const uint32_t tc1 = z15 ^ z16;
129,812✔
180
   const uint32_t tc2 = z10 ^ tc1;
129,812✔
181
   const uint32_t tc3 = z9 ^ tc2;
129,812✔
182
   const uint32_t tc4 = z0 ^ z2;
129,812✔
183
   const uint32_t tc5 = z1 ^ z0;
129,812✔
184
   const uint32_t tc6 = z3 ^ z4;
129,812✔
185
   const uint32_t tc7 = z12 ^ tc4;
129,812✔
186
   const uint32_t tc8 = z7 ^ tc6;
129,812✔
187
   const uint32_t tc9 = z8 ^ tc7;
129,812✔
188
   const uint32_t tc10 = tc8 ^ tc9;
129,812✔
189
   const uint32_t tc11 = tc6 ^ tc5;
129,812✔
190
   const uint32_t tc12 = z3 ^ z5;
129,812✔
191
   const uint32_t tc13 = z13 ^ tc1;
129,812✔
192
   const uint32_t tc14 = tc4 ^ tc12;
129,812✔
193
   const uint32_t S3 = tc3 ^ tc11;
129,812✔
194
   const uint32_t tc16 = z6 ^ tc8;
129,812✔
195
   const uint32_t tc17 = z14 ^ tc10;
129,812✔
196
   const uint32_t tc18 = ~tc13 ^ tc14;
129,812✔
197
   const uint32_t S7 = z12 ^ tc18;
129,812✔
198
   const uint32_t tc20 = z15 ^ tc16;
129,812✔
199
   const uint32_t tc21 = tc2 ^ z11;
129,812✔
200
   const uint32_t S0 = tc3 ^ tc16;
129,812✔
201
   const uint32_t S6 = tc10 ^ tc18;
129,812✔
202
   const uint32_t S4 = tc14 ^ S3;
129,812✔
203
   const uint32_t S1 = ~(S3 ^ tc16);
129,812✔
204
   const uint32_t tc26 = tc17 ^ tc20;
129,812✔
205
   const uint32_t S2 = ~(tc26 ^ z17);
129,812✔
206
   const uint32_t S5 = tc21 ^ tc17;
129,812✔
207

208
   V[0] = S0;
129,812✔
209
   V[1] = S1;
129,812✔
210
   V[2] = S2;
129,812✔
211
   V[3] = S3;
129,812✔
212
   V[4] = S4;
129,812✔
213
   V[5] = S5;
129,812✔
214
   V[6] = S6;
129,812✔
215
   V[7] = S7;
129,812✔
216
}
129,812✔
217

218
/*
219
A circuit for inverse AES Sbox of size 121 and depth 21 from
220
http://www.cs.yale.edu/homes/peralta/CircuitStuff/CMT.html
221
http://www.cs.yale.edu/homes/peralta/CircuitStuff/Sinv.txt
222
*/
223
void AES_INV_SBOX(uint32_t V[8]) {
33,060✔
224
   const uint32_t U0 = V[0];
33,060✔
225
   const uint32_t U1 = V[1];
33,060✔
226
   const uint32_t U2 = V[2];
33,060✔
227
   const uint32_t U3 = V[3];
33,060✔
228
   const uint32_t U4 = V[4];
33,060✔
229
   const uint32_t U5 = V[5];
33,060✔
230
   const uint32_t U6 = V[6];
33,060✔
231
   const uint32_t U7 = V[7];
33,060✔
232

233
   const uint32_t Y0 = U0 ^ U3;
33,060✔
234
   const uint32_t Y2 = ~(U1 ^ U3);
33,060✔
235
   const uint32_t Y4 = U0 ^ Y2;
33,060✔
236
   const uint32_t RTL0 = U6 ^ U7;
33,060✔
237
   const uint32_t Y1 = Y2 ^ RTL0;
33,060✔
238
   const uint32_t Y7 = ~(U2 ^ Y1);
33,060✔
239
   const uint32_t RTL1 = U3 ^ U4;
33,060✔
240
   const uint32_t Y6 = ~(U7 ^ RTL1);
33,060✔
241
   const uint32_t Y3 = Y1 ^ RTL1;
33,060✔
242
   const uint32_t RTL2 = ~(U0 ^ U2);
33,060✔
243
   const uint32_t Y5 = U5 ^ RTL2;
33,060✔
244
   const uint32_t sa1 = Y0 ^ Y2;
33,060✔
245
   const uint32_t sa0 = Y1 ^ Y3;
33,060✔
246
   const uint32_t sb1 = Y4 ^ Y6;
33,060✔
247
   const uint32_t sb0 = Y5 ^ Y7;
33,060✔
248
   const uint32_t ah = Y0 ^ Y1;
33,060✔
249
   const uint32_t al = Y2 ^ Y3;
33,060✔
250
   const uint32_t aa = sa0 ^ sa1;
33,060✔
251
   const uint32_t bh = Y4 ^ Y5;
33,060✔
252
   const uint32_t bl = Y6 ^ Y7;
33,060✔
253
   const uint32_t bb = sb0 ^ sb1;
33,060✔
254
   const uint32_t ab20 = sa0 ^ sb0;
33,060✔
255
   const uint32_t ab22 = al ^ bl;
33,060✔
256
   const uint32_t ab23 = Y3 ^ Y7;
33,060✔
257
   const uint32_t ab21 = sa1 ^ sb1;
33,060✔
258
   const uint32_t abcd1 = ah & bh;
33,060✔
259
   const uint32_t rr1 = Y0 & Y4;
33,060✔
260
   const uint32_t ph11 = ab20 ^ abcd1;
33,060✔
261
   const uint32_t t01 = Y1 & Y5;
33,060✔
262
   const uint32_t ph01 = t01 ^ abcd1;
33,060✔
263
   const uint32_t abcd2 = al & bl;
33,060✔
264
   const uint32_t r1 = Y2 & Y6;
33,060✔
265
   const uint32_t pl11 = ab22 ^ abcd2;
33,060✔
266
   const uint32_t r2 = Y3 & Y7;
33,060✔
267
   const uint32_t pl01 = r2 ^ abcd2;
33,060✔
268
   const uint32_t r3 = sa0 & sb0;
33,060✔
269
   const uint32_t vr1 = aa & bb;
33,060✔
270
   const uint32_t pr1 = vr1 ^ r3;
33,060✔
271
   const uint32_t wr1 = sa1 & sb1;
33,060✔
272
   const uint32_t qr1 = wr1 ^ r3;
33,060✔
273
   const uint32_t ab0 = ph11 ^ rr1;
33,060✔
274
   const uint32_t ab1 = ph01 ^ ab21;
33,060✔
275
   const uint32_t ab2 = pl11 ^ r1;
33,060✔
276
   const uint32_t ab3 = pl01 ^ qr1;
33,060✔
277
   const uint32_t cp1 = ab0 ^ pr1;
33,060✔
278
   const uint32_t cp2 = ab1 ^ qr1;
33,060✔
279
   const uint32_t cp3 = ab2 ^ pr1;
33,060✔
280
   const uint32_t cp4 = ab3 ^ ab23;
33,060✔
281
   const uint32_t tinv1 = cp3 ^ cp4;
33,060✔
282
   const uint32_t tinv2 = cp3 & cp1;
33,060✔
283
   const uint32_t tinv3 = cp2 ^ tinv2;
33,060✔
284
   const uint32_t tinv4 = cp1 ^ cp2;
33,060✔
285
   const uint32_t tinv5 = cp4 ^ tinv2;
33,060✔
286
   const uint32_t tinv6 = tinv5 & tinv4;
33,060✔
287
   const uint32_t tinv7 = tinv3 & tinv1;
33,060✔
288
   const uint32_t d2 = cp4 ^ tinv7;
33,060✔
289
   const uint32_t d0 = cp2 ^ tinv6;
33,060✔
290
   const uint32_t tinv8 = cp1 & cp4;
33,060✔
291
   const uint32_t tinv9 = tinv4 & tinv8;
33,060✔
292
   const uint32_t tinv10 = tinv4 ^ tinv2;
33,060✔
293
   const uint32_t d1 = tinv9 ^ tinv10;
33,060✔
294
   const uint32_t tinv11 = cp2 & cp3;
33,060✔
295
   const uint32_t tinv12 = tinv1 & tinv11;
33,060✔
296
   const uint32_t tinv13 = tinv1 ^ tinv2;
33,060✔
297
   const uint32_t d3 = tinv12 ^ tinv13;
33,060✔
298
   const uint32_t sd1 = d1 ^ d3;
33,060✔
299
   const uint32_t sd0 = d0 ^ d2;
33,060✔
300
   const uint32_t dl = d0 ^ d1;
33,060✔
301
   const uint32_t dh = d2 ^ d3;
33,060✔
302
   const uint32_t dd = sd0 ^ sd1;
33,060✔
303
   const uint32_t abcd3 = dh & bh;
33,060✔
304
   const uint32_t rr2 = d3 & Y4;
33,060✔
305
   const uint32_t t02 = d2 & Y5;
33,060✔
306
   const uint32_t abcd4 = dl & bl;
33,060✔
307
   const uint32_t r4 = d1 & Y6;
33,060✔
308
   const uint32_t r5 = d0 & Y7;
33,060✔
309
   const uint32_t r6 = sd0 & sb0;
33,060✔
310
   const uint32_t vr2 = dd & bb;
33,060✔
311
   const uint32_t wr2 = sd1 & sb1;
33,060✔
312
   const uint32_t abcd5 = dh & ah;
33,060✔
313
   const uint32_t r7 = d3 & Y0;
33,060✔
314
   const uint32_t r8 = d2 & Y1;
33,060✔
315
   const uint32_t abcd6 = dl & al;
33,060✔
316
   const uint32_t r9 = d1 & Y2;
33,060✔
317
   const uint32_t r10 = d0 & Y3;
33,060✔
318
   const uint32_t r11 = sd0 & sa0;
33,060✔
319
   const uint32_t vr3 = dd & aa;
33,060✔
320
   const uint32_t wr3 = sd1 & sa1;
33,060✔
321
   const uint32_t ph12 = rr2 ^ abcd3;
33,060✔
322
   const uint32_t ph02 = t02 ^ abcd3;
33,060✔
323
   const uint32_t pl12 = r4 ^ abcd4;
33,060✔
324
   const uint32_t pl02 = r5 ^ abcd4;
33,060✔
325
   const uint32_t pr2 = vr2 ^ r6;
33,060✔
326
   const uint32_t qr2 = wr2 ^ r6;
33,060✔
327
   const uint32_t p0 = ph12 ^ pr2;
33,060✔
328
   const uint32_t p1 = ph02 ^ qr2;
33,060✔
329
   const uint32_t p2 = pl12 ^ pr2;
33,060✔
330
   const uint32_t p3 = pl02 ^ qr2;
33,060✔
331
   const uint32_t ph13 = r7 ^ abcd5;
33,060✔
332
   const uint32_t ph03 = r8 ^ abcd5;
33,060✔
333
   const uint32_t pl13 = r9 ^ abcd6;
33,060✔
334
   const uint32_t pl03 = r10 ^ abcd6;
33,060✔
335
   const uint32_t pr3 = vr3 ^ r11;
33,060✔
336
   const uint32_t qr3 = wr3 ^ r11;
33,060✔
337
   const uint32_t p4 = ph13 ^ pr3;
33,060✔
338
   const uint32_t S7 = ph03 ^ qr3;
33,060✔
339
   const uint32_t p6 = pl13 ^ pr3;
33,060✔
340
   const uint32_t p7 = pl03 ^ qr3;
33,060✔
341
   const uint32_t S3 = p1 ^ p6;
33,060✔
342
   const uint32_t S6 = p2 ^ p6;
33,060✔
343
   const uint32_t S0 = p3 ^ p6;
33,060✔
344
   const uint32_t X11 = p0 ^ p2;
33,060✔
345
   const uint32_t S5 = S0 ^ X11;
33,060✔
346
   const uint32_t X13 = p4 ^ p7;
33,060✔
347
   const uint32_t X14 = X11 ^ X13;
33,060✔
348
   const uint32_t S1 = S3 ^ X14;
33,060✔
349
   const uint32_t X16 = p1 ^ S7;
33,060✔
350
   const uint32_t S2 = X14 ^ X16;
33,060✔
351
   const uint32_t X18 = p0 ^ p4;
33,060✔
352
   const uint32_t X19 = S5 ^ X16;
33,060✔
353
   const uint32_t S4 = X18 ^ X19;
33,060✔
354

355
   V[0] = S0;
33,060✔
356
   V[1] = S1;
33,060✔
357
   V[2] = S2;
33,060✔
358
   V[3] = S3;
33,060✔
359
   V[4] = S4;
33,060✔
360
   V[5] = S5;
33,060✔
361
   V[6] = S6;
33,060✔
362
   V[7] = S7;
33,060✔
363
}
33,060✔
364

365
inline void bit_transpose(uint32_t B[8]) {
19,732✔
366
   swap_bits<uint32_t>(B[1], B[0], 0x55555555, 1);
19,732✔
367
   swap_bits<uint32_t>(B[3], B[2], 0x55555555, 1);
19,732✔
368
   swap_bits<uint32_t>(B[5], B[4], 0x55555555, 1);
19,732✔
369
   swap_bits<uint32_t>(B[7], B[6], 0x55555555, 1);
19,732✔
370

371
   swap_bits<uint32_t>(B[2], B[0], 0x33333333, 2);
19,732✔
372
   swap_bits<uint32_t>(B[3], B[1], 0x33333333, 2);
19,732✔
373
   swap_bits<uint32_t>(B[6], B[4], 0x33333333, 2);
19,732✔
374
   swap_bits<uint32_t>(B[7], B[5], 0x33333333, 2);
19,732✔
375

376
   swap_bits<uint32_t>(B[4], B[0], 0x0F0F0F0F, 4);
19,732✔
377
   swap_bits<uint32_t>(B[5], B[1], 0x0F0F0F0F, 4);
19,732✔
378
   swap_bits<uint32_t>(B[6], B[2], 0x0F0F0F0F, 4);
19,732✔
379
   swap_bits<uint32_t>(B[7], B[3], 0x0F0F0F0F, 4);
19,732✔
380
}
19,732✔
381

382
inline void ks_expand(uint32_t B[8], const uint32_t K[], size_t r) {
85,565✔
383
   /*
384
   This is bit_transpose of K[r..r+4] || K[r..r+4], we can save some computation
385
   due to knowing the first and second halves are the same data.
386
   */
387
   for(size_t i = 0; i != 4; ++i)
427,825✔
388
      B[i] = K[r + i];
342,260✔
389

390
   swap_bits<uint32_t>(B[1], B[0], 0x55555555, 1);
85,565✔
391
   swap_bits<uint32_t>(B[3], B[2], 0x55555555, 1);
85,565✔
392

393
   swap_bits<uint32_t>(B[2], B[0], 0x33333333, 2);
85,565✔
394
   swap_bits<uint32_t>(B[3], B[1], 0x33333333, 2);
85,565✔
395

396
   B[4] = B[0];
85,565✔
397
   B[5] = B[1];
85,565✔
398
   B[6] = B[2];
85,565✔
399
   B[7] = B[3];
85,565✔
400

401
   swap_bits<uint32_t>(B[4], B[0], 0x0F0F0F0F, 4);
85,565✔
402
   swap_bits<uint32_t>(B[5], B[1], 0x0F0F0F0F, 4);
85,565✔
403
   swap_bits<uint32_t>(B[6], B[2], 0x0F0F0F0F, 4);
85,565✔
404
   swap_bits<uint32_t>(B[7], B[3], 0x0F0F0F0F, 4);
85,565✔
405
}
85,565✔
406

407
inline void shift_rows(uint32_t B[8]) {
85,548✔
408
   // 3 0 1 2 7 4 5 6 10 11 8 9 14 15 12 13 17 18 19 16 21 22 23 20 24 25 26 27 28 29 30 31
409
#if defined(BOTAN_TARGET_CPU_HAS_NATIVE_64BIT)
410
   for(size_t i = 0; i != 8; i += 2) {
427,740✔
411
      uint64_t x = (static_cast<uint64_t>(B[i]) << 32) | B[i + 1];
342,192✔
412
      x = bit_permute_step<uint64_t>(x, 0x0022331100223311, 2);
342,192✔
413
      x = bit_permute_step<uint64_t>(x, 0x0055005500550055, 1);
342,192✔
414
      B[i] = static_cast<uint32_t>(x >> 32);
342,192✔
415
      B[i + 1] = static_cast<uint32_t>(x);
342,192✔
416
   }
417
#else
418
   for(size_t i = 0; i != 8; ++i) {
419
      uint32_t x = B[i];
420
      x = bit_permute_step<uint32_t>(x, 0x00223311, 2);
421
      x = bit_permute_step<uint32_t>(x, 0x00550055, 1);
422
      B[i] = x;
423
   }
424
#endif
425
}
85,548✔
426

427
inline void inv_shift_rows(uint32_t B[8]) {
33,060✔
428
   // Inverse of shift_rows, just inverting the steps
429

430
#if defined(BOTAN_TARGET_CPU_HAS_NATIVE_64BIT)
431
   for(size_t i = 0; i != 8; i += 2) {
165,300✔
432
      uint64_t x = (static_cast<uint64_t>(B[i]) << 32) | B[i + 1];
132,240✔
433
      x = bit_permute_step<uint64_t>(x, 0x0055005500550055, 1);
132,240✔
434
      x = bit_permute_step<uint64_t>(x, 0x0022331100223311, 2);
132,240✔
435
      B[i] = static_cast<uint32_t>(x >> 32);
132,240✔
436
      B[i + 1] = static_cast<uint32_t>(x);
132,240✔
437
   }
438
#else
439
   for(size_t i = 0; i != 8; ++i) {
440
      uint32_t x = B[i];
441
      x = bit_permute_step<uint32_t>(x, 0x00550055, 1);
442
      x = bit_permute_step<uint32_t>(x, 0x00223311, 2);
443
      B[i] = x;
444
   }
445
#endif
446
}
33,060✔
447

448
inline void mix_columns(uint32_t B[8]) {
108,742✔
449
   // carry high bits in B[0] to positions in 0x1b == 0b11011
450
   const uint32_t X2[8] = {
108,742✔
451
      B[1],
452
      B[2],
453
      B[3],
454
      B[4] ^ B[0],
108,742✔
455
      B[5] ^ B[0],
108,742✔
456
      B[6],
457
      B[7] ^ B[0],
108,742✔
458
      B[0],
459
   };
108,742✔
460

461
   for(size_t i = 0; i != 8; i++) {
978,678✔
462
      const uint32_t X3 = B[i] ^ X2[i];
869,936✔
463
      B[i] = X2[i] ^ rotr<8>(B[i]) ^ rotr<16>(B[i]) ^ rotr<24>(X3);
869,936✔
464
   }
465
}
108,742✔
466

467
void inv_mix_columns(uint32_t B[8]) {
30,348✔
468
   /*
469
   OpenSSL's bsaes implementation credits Jussi Kivilinna with the lovely
470
   matrix decomposition
471

472
   | 0e 0b 0d 09 |   | 02 03 01 01 |   | 05 00 04 00 |
473
   | 09 0e 0b 0d | = | 01 02 03 01 | x | 00 05 00 04 |
474
   | 0d 09 0e 0b |   | 01 01 02 03 |   | 04 00 05 00 |
475
   | 0b 0d 09 0e |   | 03 01 01 02 |   | 00 04 00 05 |
476

477
   Notice the first component is simply the MixColumns matrix. So we can
478
   multiply first by (05,00,04,00) then perform MixColumns to get the equivalent
479
   of InvMixColumn.
480
   */
481
   const uint32_t X4[8] = {
30,348✔
482
      B[2],
483
      B[3],
484
      B[4] ^ B[0],
30,348✔
485
      B[5] ^ B[0] ^ B[1],
30,348✔
486
      B[6] ^ B[1],
30,348✔
487
      B[7] ^ B[0],
30,348✔
488
      B[0] ^ B[1],
30,348✔
489
      B[1],
490
   };
30,348✔
491

492
   for(size_t i = 0; i != 8; i++) {
273,132✔
493
      const uint32_t X5 = X4[i] ^ B[i];
242,784✔
494
      B[i] = X5 ^ rotr<16>(X4[i]);
242,784✔
495
   }
496

497
   mix_columns(B);
30,348✔
498
}
30,348✔
499

500
/*
501
* AES Encryption
502
*/
503
void aes_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks, const secure_vector<uint32_t>& EK) {
4,997✔
504
   BOTAN_ASSERT(EK.size() == 44 || EK.size() == 52 || EK.size() == 60, "Key was set");
4,997✔
505

506
   const size_t rounds = (EK.size() - 4) / 4;
4,997✔
507

508
   uint32_t KS[13 * 8] = {0};  // actual maximum is (rounds - 1) * 8
4,997✔
509
   for(size_t i = 0; i < rounds - 1; i += 1) {
60,404✔
510
      ks_expand(&KS[8 * i], EK.data(), 4 * i + 4);
55,407✔
511
   }
512

513
   const size_t BLOCK_SIZE = 16;
4,997✔
514
   const size_t BITSLICED_BLOCKS = 8 * sizeof(uint32_t) / BLOCK_SIZE;
4,997✔
515

516
   while(blocks > 0) {
12,151✔
517
      const size_t this_loop = std::min(blocks, BITSLICED_BLOCKS);
7,154✔
518

519
      uint32_t B[8] = {0};
7,154✔
520

521
      load_be(B, in, this_loop * 4);
7,154✔
522

523
      CT::poison(B, 8);
7,154✔
524

525
      for(size_t i = 0; i != 8; ++i)
64,386✔
526
         B[i] ^= EK[i % 4];
57,232✔
527

528
      bit_transpose(B);
7,154✔
529

530
      for(size_t r = 0; r != rounds - 1; ++r) {
85,548✔
531
         AES_SBOX(B);
78,394✔
532
         shift_rows(B);
78,394✔
533
         mix_columns(B);
78,394✔
534

535
         for(size_t i = 0; i != 8; ++i)
705,546✔
536
            B[i] ^= KS[8 * r + i];
627,152✔
537
      }
538

539
      // Final round:
540
      AES_SBOX(B);
7,154✔
541
      shift_rows(B);
7,154✔
542
      bit_transpose(B);
7,154✔
543

544
      for(size_t i = 0; i != 8; ++i)
64,386✔
545
         B[i] ^= EK[4 * rounds + i % 4];
57,232✔
546

547
      CT::unpoison(B, 8);
7,154✔
548

549
      copy_out_be(out, this_loop * 4 * sizeof(uint32_t), B);
7,154✔
550

551
      in += this_loop * BLOCK_SIZE;
7,154✔
552
      out += this_loop * BLOCK_SIZE;
7,154✔
553
      blocks -= this_loop;
7,154✔
554
   }
555
}
4,997✔
556

557
/*
558
* AES Decryption
559
*/
560
void aes_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks, const secure_vector<uint32_t>& DK) {
2,694✔
561
   BOTAN_ASSERT(DK.size() == 44 || DK.size() == 52 || DK.size() == 60, "Key was set");
2,694✔
562

563
   const size_t rounds = (DK.size() - 4) / 4;
2,694✔
564

565
   uint32_t KS[13 * 8] = {0};  // actual maximum is (rounds - 1) * 8
2,694✔
566
   for(size_t i = 0; i < rounds - 1; i += 1) {
32,852✔
567
      ks_expand(&KS[8 * i], DK.data(), 4 * i + 4);
30,158✔
568
   }
569

570
   const size_t BLOCK_SIZE = 16;
2,694✔
571
   const size_t BITSLICED_BLOCKS = 8 * sizeof(uint32_t) / BLOCK_SIZE;
2,694✔
572

573
   while(blocks > 0) {
5,406✔
574
      const size_t this_loop = std::min(blocks, BITSLICED_BLOCKS);
2,712✔
575

576
      uint32_t B[8] = {0};
2,712✔
577

578
      CT::poison(B, 8);
2,712✔
579

580
      load_be(B, in, this_loop * 4);
2,712✔
581

582
      for(size_t i = 0; i != 8; ++i)
24,408✔
583
         B[i] ^= DK[i % 4];
21,696✔
584

585
      bit_transpose(B);
2,712✔
586

587
      for(size_t r = 0; r != rounds - 1; ++r) {
33,060✔
588
         AES_INV_SBOX(B);
30,348✔
589
         inv_shift_rows(B);
30,348✔
590
         inv_mix_columns(B);
30,348✔
591

592
         for(size_t i = 0; i != 8; ++i)
273,132✔
593
            B[i] ^= KS[8 * r + i];
242,784✔
594
      }
595

596
      // Final round:
597
      AES_INV_SBOX(B);
2,712✔
598
      inv_shift_rows(B);
2,712✔
599
      bit_transpose(B);
2,712✔
600

601
      for(size_t i = 0; i != 8; ++i)
24,408✔
602
         B[i] ^= DK[4 * rounds + i % 4];
21,696✔
603

604
      CT::unpoison(B, 8);
2,712✔
605

606
      copy_out_be(out, this_loop * 4 * sizeof(uint32_t), B);
2,712✔
607

608
      in += this_loop * BLOCK_SIZE;
2,712✔
609
      out += this_loop * BLOCK_SIZE;
2,712✔
610
      blocks -= this_loop;
2,712✔
611
   }
612
}
2,694✔
613

614
inline uint32_t xtime32(uint32_t s) {
188,808✔
615
   const uint32_t lo_bit = 0x01010101;
188,808✔
616
   const uint32_t mask = 0x7F7F7F7F;
188,808✔
617
   const uint32_t poly = 0x1B;
188,808✔
618

619
   return ((s & mask) << 1) ^ (((s >> 7) & lo_bit) * poly);
188,808✔
620
}
621

622
inline uint32_t InvMixColumn(uint32_t s1) {
188,808✔
623
   const uint32_t s2 = xtime32(s1);
188,808✔
624
   const uint32_t s4 = xtime32(s2);
188,808✔
625
   const uint32_t s8 = xtime32(s4);
188,808✔
626
   const uint32_t s9 = s8 ^ s1;
188,808✔
627
   const uint32_t s11 = s9 ^ s2;
188,808✔
628
   const uint32_t s13 = s9 ^ s4;
188,808✔
629
   const uint32_t s14 = s8 ^ s4 ^ s2;
188,808✔
630

631
   return s14 ^ rotr<8>(s9) ^ rotr<16>(s13) ^ rotr<24>(s11);
188,808✔
632
}
633

634
void InvMixColumn_x4(uint32_t x[4]) {
47,202✔
635
   x[0] = InvMixColumn(x[0]);
47,202✔
636
   x[1] = InvMixColumn(x[1]);
47,202✔
637
   x[2] = InvMixColumn(x[2]);
47,202✔
638
   x[3] = InvMixColumn(x[3]);
47,202✔
639
}
47,202✔
640

641
uint32_t SE_word(uint32_t x) {
44,264✔
642
   uint32_t I[8] = {0};
44,264✔
643

644
   for(size_t i = 0; i != 8; ++i)
398,376✔
645
      I[i] = (x >> (7 - i)) & 0x01010101;
354,112✔
646

647
   AES_SBOX(I);
44,264✔
648

649
   x = 0;
44,264✔
650

651
   for(size_t i = 0; i != 8; ++i)
398,376✔
652
      x |= ((I[i] & 0x01010101) << (7 - i));
354,112✔
653

654
   return x;
44,264✔
655
}
656

657
void aes_key_schedule(const uint8_t key[],
4,226✔
658
                      size_t length,
659
                      secure_vector<uint32_t>& EK,
660
                      secure_vector<uint32_t>& DK,
661
                      bool bswap_keys = false) {
662
   static const uint32_t RC[10] = {0x01000000,
4,226✔
663
                                   0x02000000,
664
                                   0x04000000,
665
                                   0x08000000,
666
                                   0x10000000,
667
                                   0x20000000,
668
                                   0x40000000,
669
                                   0x80000000,
670
                                   0x1B000000,
671
                                   0x36000000};
672

673
   const size_t X = length / 4;
4,226✔
674

675
   // Can't happen, but make static analyzers happy
676
   BOTAN_ASSERT_NOMSG(X == 4 || X == 6 || X == 8);
4,226✔
677

678
   const size_t rounds = (length / 4) + 6;
4,226✔
679

680
   // Help the optimizer
681
   BOTAN_ASSERT_NOMSG(rounds == 10 || rounds == 12 || rounds == 14);
4,226✔
682

683
   CT::poison(key, length);
4,226✔
684

685
   EK.resize(length + 28);
4,226✔
686
   DK.resize(length + 28);
4,226✔
687

688
   for(size_t i = 0; i != X; ++i)
30,298✔
689
      EK[i] = load_be<uint32_t>(key, i);
26,072✔
690

691
   for(size_t i = X; i < 4 * (rounds + 1); i += X) {
38,914✔
692
      EK[i] = EK[i - X] ^ RC[(i - X) / X] ^ rotl<8>(SE_word(EK[i - 1]));
34,688✔
693

694
      for(size_t j = 1; j != X && (i + j) < EK.size(); ++j) {
196,544✔
695
         EK[i + j] = EK[i + j - X];
161,856✔
696

697
         if(X == 8 && j == 4)
161,856✔
698
            EK[i + j] ^= SE_word(EK[i + j - 1]);
9,576✔
699
         else
700
            EK[i + j] ^= EK[i + j - 1];
152,280✔
701
      }
702
   }
703

704
   for(size_t i = 0; i != 4 * (rounds + 1); i += 4) {
59,880✔
705
      DK[i] = EK[4 * rounds - i];
55,654✔
706
      DK[i + 1] = EK[4 * rounds - i + 1];
55,654✔
707
      DK[i + 2] = EK[4 * rounds - i + 2];
55,654✔
708
      DK[i + 3] = EK[4 * rounds - i + 3];
55,654✔
709
   }
710

711
   for(size_t i = 4; i != 4 * rounds; i += 4) {
51,428✔
712
      InvMixColumn_x4(&DK[i]);
47,202✔
713
   }
714

715
   if(bswap_keys) {
4,226✔
716
      // HW AES on little endian needs the subkeys to be byte reversed
717
      for(size_t i = 0; i != EK.size(); ++i)
×
718
         EK[i] = reverse_bytes(EK[i]);
×
719
      for(size_t i = 0; i != DK.size(); ++i)
×
720
         DK[i] = reverse_bytes(DK[i]);
×
721
   }
722

723
   CT::unpoison(EK.data(), EK.size());
4,226✔
724
   CT::unpoison(DK.data(), DK.size());
4,226✔
725
   CT::unpoison(key, length);
4,226✔
726
}
4,226✔
727

728
size_t aes_parallelism() {
212,491✔
729
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
730
   if(CPUID::has_hw_aes()) {
212,491✔
731
      return 4;  // pipelined
732
   }
733
#endif
734

735
#if defined(BOTAN_HAS_AES_VPERM)
736
   if(CPUID::has_vperm()) {
9,114✔
737
      return 2;  // pipelined
738
   }
739
#endif
740

741
   // bitsliced:
742
   return 2;
743
}
744

745
const char* aes_provider() {
4,041✔
746
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
747
   if(CPUID::has_hw_aes()) {
4,041✔
748
      return "cpu";
749
   }
750
#endif
751

752
#if defined(BOTAN_HAS_AES_VPERM)
753
   if(CPUID::has_vperm()) {
2,694✔
754
      return "vperm";
1,347✔
755
   }
756
#endif
757

758
   return "base";
759
}
760

761
}
762

763
std::string AES_128::provider() const { return aes_provider(); }
1,149✔
764

765
std::string AES_192::provider() const { return aes_provider(); }
1,350✔
766

767
std::string AES_256::provider() const { return aes_provider(); }
1,542✔
768

769
size_t AES_128::parallelism() const { return aes_parallelism(); }
12,871✔
770

771
size_t AES_192::parallelism() const { return aes_parallelism(); }
4,840✔
772

773
size_t AES_256::parallelism() const { return aes_parallelism(); }
194,780✔
774

775
bool AES_128::has_keying_material() const { return !m_EK.empty(); }
222,033✔
776

777
bool AES_192::has_keying_material() const { return !m_EK.empty(); }
53,324✔
778

779
bool AES_256::has_keying_material() const { return !m_EK.empty(); }
985,086✔
780

781
void AES_128::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
144,642✔
782
   assert_key_material_set();
144,642✔
783

784
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
785
   if(CPUID::has_hw_aes()) {
139,713✔
786
      return hw_aes_encrypt_n(in, out, blocks);
136,011✔
787
   }
788
#endif
789

790
#if defined(BOTAN_HAS_AES_VPERM)
791
   if(CPUID::has_vperm()) {
3,702✔
792
      return vperm_encrypt_n(in, out, blocks);
2,085✔
793
   }
794
#endif
795

796
   aes_encrypt_n(in, out, blocks, m_EK);
1,617✔
797
}
798

799
void AES_128::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
21,567✔
800
   assert_key_material_set();
21,567✔
801

802
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
803
   if(CPUID::has_hw_aes()) {
19,268✔
804
      return hw_aes_decrypt_n(in, out, blocks);
17,736✔
805
   }
806
#endif
807

808
#if defined(BOTAN_HAS_AES_VPERM)
809
   if(CPUID::has_vperm()) {
1,532✔
810
      return vperm_decrypt_n(in, out, blocks);
766✔
811
   }
812
#endif
813

814
   aes_decrypt_n(in, out, blocks, m_DK);
766✔
815
}
816

817
void AES_128::key_schedule(const uint8_t key[], size_t length) {
11,223✔
818
#if defined(BOTAN_HAS_AES_NI)
819
   if(CPUID::has_aes_ni()) {
11,223✔
820
      return aesni_key_schedule(key, length);
8,658✔
821
   }
822
#endif
823

824
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
825
   if(CPUID::has_hw_aes()) {
2,565✔
826
      return aes_key_schedule(key, length, m_EK, m_DK, CPUID::is_little_endian());
×
827
   }
828
#endif
829

830
#if defined(BOTAN_HAS_AES_VPERM)
831
   if(CPUID::has_vperm()) {
2,565✔
832
      return vperm_key_schedule(key, length);
1,327✔
833
   }
834
#endif
835

836
   aes_key_schedule(key, length, m_EK, m_DK);
1,238✔
837
}
838

839
void AES_128::clear() {
7,076✔
840
   zap(m_EK);
7,076✔
841
   zap(m_DK);
7,076✔
842
}
7,076✔
843

844
void AES_192::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
29,406✔
845
   assert_key_material_set();
29,406✔
846

847
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
848
   if(CPUID::has_hw_aes()) {
26,654✔
849
      return hw_aes_encrypt_n(in, out, blocks);
23,375✔
850
   }
851
#endif
852

853
#if defined(BOTAN_HAS_AES_VPERM)
854
   if(CPUID::has_vperm()) {
3,279✔
855
      return vperm_encrypt_n(in, out, blocks);
1,736✔
856
   }
857
#endif
858

859
   aes_encrypt_n(in, out, blocks, m_EK);
1,543✔
860
}
861

862
void AES_192::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
6,162✔
863
   assert_key_material_set();
6,162✔
864

865
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
866
   if(CPUID::has_hw_aes()) {
3,462✔
867
      return hw_aes_decrypt_n(in, out, blocks);
1,662✔
868
   }
869
#endif
870

871
#if defined(BOTAN_HAS_AES_VPERM)
872
   if(CPUID::has_vperm()) {
1,800✔
873
      return vperm_decrypt_n(in, out, blocks);
900✔
874
   }
875
#endif
876

877
   aes_decrypt_n(in, out, blocks, m_DK);
900✔
878
}
879

880
void AES_192::key_schedule(const uint8_t key[], size_t length) {
4,633✔
881
#if defined(BOTAN_HAS_AES_NI)
882
   if(CPUID::has_aes_ni()) {
4,633✔
883
      return aesni_key_schedule(key, length);
1,807✔
884
   }
885
#endif
886

887
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
888
   if(CPUID::has_hw_aes()) {
2,826✔
889
      return aes_key_schedule(key, length, m_EK, m_DK, CPUID::is_little_endian());
×
890
   }
891
#endif
892

893
#if defined(BOTAN_HAS_AES_VPERM)
894
   if(CPUID::has_vperm()) {
2,826✔
895
      return vperm_key_schedule(key, length);
1,434✔
896
   }
897
#endif
898

899
   aes_key_schedule(key, length, m_EK, m_DK);
1,392✔
900
}
901

902
void AES_192::clear() {
3,164✔
903
   zap(m_EK);
3,164✔
904
   zap(m_DK);
3,164✔
905
}
3,164✔
906

907
void AES_256::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
598,423✔
908
   assert_key_material_set();
598,423✔
909

910
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
911
   if(CPUID::has_hw_aes()) {
595,278✔
912
      return hw_aes_encrypt_n(in, out, blocks);
591,309✔
913
   }
914
#endif
915

916
#if defined(BOTAN_HAS_AES_VPERM)
917
   if(CPUID::has_vperm()) {
3,969✔
918
      return vperm_encrypt_n(in, out, blocks);
2,132✔
919
   }
920
#endif
921

922
   aes_encrypt_n(in, out, blocks, m_EK);
1,837✔
923
}
924

925
void AES_256::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
12,277✔
926
   assert_key_material_set();
12,277✔
927

928
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
929
   if(CPUID::has_hw_aes()) {
9,189✔
930
      return hw_aes_decrypt_n(in, out, blocks);
7,133✔
931
   }
932
#endif
933

934
#if defined(BOTAN_HAS_AES_VPERM)
935
   if(CPUID::has_vperm()) {
2,056✔
936
      return vperm_decrypt_n(in, out, blocks);
1,028✔
937
   }
938
#endif
939

940
   aes_decrypt_n(in, out, blocks, m_DK);
1,028✔
941
}
942

943
void AES_256::key_schedule(const uint8_t key[], size_t length) {
113,178✔
944
#if defined(BOTAN_HAS_AES_NI)
945
   if(CPUID::has_aes_ni()) {
113,178✔
946
      return aesni_key_schedule(key, length);
109,932✔
947
   }
948
#endif
949

950
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
951
   if(CPUID::has_hw_aes()) {
3,246✔
952
      return aes_key_schedule(key, length, m_EK, m_DK, CPUID::is_little_endian());
×
953
   }
954
#endif
955

956
#if defined(BOTAN_HAS_AES_VPERM)
957
   if(CPUID::has_vperm()) {
3,246✔
958
      return vperm_key_schedule(key, length);
1,650✔
959
   }
960
#endif
961

962
   aes_key_schedule(key, length, m_EK, m_DK);
1,596✔
963
}
964

965
void AES_256::clear() {
4,306✔
966
   zap(m_EK);
4,306✔
967
   zap(m_DK);
4,306✔
968
}
4,306✔
969

970
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc