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

randombit / botan / 5123321399

30 May 2023 04:06PM UTC coverage: 92.213% (+0.004%) from 92.209%
5123321399

Pull #3558

github

web-flow
Merge dd72f7389 into 057bcbc35
Pull Request #3558: Add braces around all if/else statements

75602 of 81986 relevant lines covered (92.21%)

11859779.3 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

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

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

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

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

408
inline void shift_rows(uint32_t B[8]) {
85,548✔
409
   // 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
410
#if defined(BOTAN_TARGET_CPU_HAS_NATIVE_64BIT)
411
   for(size_t i = 0; i != 8; i += 2) {
427,740✔
412
      uint64_t x = (static_cast<uint64_t>(B[i]) << 32) | B[i + 1];
342,192✔
413
      x = bit_permute_step<uint64_t>(x, 0x0022331100223311, 2);
342,192✔
414
      x = bit_permute_step<uint64_t>(x, 0x0055005500550055, 1);
342,192✔
415
      B[i] = static_cast<uint32_t>(x >> 32);
342,192✔
416
      B[i + 1] = static_cast<uint32_t>(x);
342,192✔
417
   }
418
#else
419
   for(size_t i = 0; i != 8; ++i) {
420
      uint32_t x = B[i];
421
      x = bit_permute_step<uint32_t>(x, 0x00223311, 2);
422
      x = bit_permute_step<uint32_t>(x, 0x00550055, 1);
423
      B[i] = x;
424
   }
425
#endif
426
}
85,548✔
427

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

530
      bit_transpose(B);
7,154✔
531

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

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

542
      // Final round:
543
      AES_SBOX(B);
7,154✔
544
      shift_rows(B);
7,154✔
545
      bit_transpose(B);
7,154✔
546

547
      for(size_t i = 0; i != 8; ++i) {
64,386✔
548
         B[i] ^= EK[4 * rounds + i % 4];
57,232✔
549
      }
550

551
      CT::unpoison(B, 8);
7,154✔
552

553
      copy_out_be(out, this_loop * 4 * sizeof(uint32_t), B);
7,154✔
554

555
      in += this_loop * BLOCK_SIZE;
7,154✔
556
      out += this_loop * BLOCK_SIZE;
7,154✔
557
      blocks -= this_loop;
7,154✔
558
   }
559
}
4,997✔
560

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

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

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

574
   const size_t BLOCK_SIZE = 16;
2,694✔
575
   const size_t BITSLICED_BLOCKS = 8 * sizeof(uint32_t) / BLOCK_SIZE;
2,694✔
576

577
   while(blocks > 0) {
5,406✔
578
      const size_t this_loop = std::min(blocks, BITSLICED_BLOCKS);
2,712✔
579

580
      uint32_t B[8] = {0};
2,712✔
581

582
      CT::poison(B, 8);
2,712✔
583

584
      load_be(B, in, this_loop * 4);
2,712✔
585

586
      for(size_t i = 0; i != 8; ++i) {
24,408✔
587
         B[i] ^= DK[i % 4];
21,696✔
588
      }
589

590
      bit_transpose(B);
2,712✔
591

592
      for(size_t r = 0; r != rounds - 1; ++r) {
33,060✔
593
         AES_INV_SBOX(B);
30,348✔
594
         inv_shift_rows(B);
30,348✔
595
         inv_mix_columns(B);
30,348✔
596

597
         for(size_t i = 0; i != 8; ++i) {
273,132✔
598
            B[i] ^= KS[8 * r + i];
242,784✔
599
         }
600
      }
601

602
      // Final round:
603
      AES_INV_SBOX(B);
2,712✔
604
      inv_shift_rows(B);
2,712✔
605
      bit_transpose(B);
2,712✔
606

607
      for(size_t i = 0; i != 8; ++i) {
24,408✔
608
         B[i] ^= DK[4 * rounds + i % 4];
21,696✔
609
      }
610

611
      CT::unpoison(B, 8);
2,712✔
612

613
      copy_out_be(out, this_loop * 4 * sizeof(uint32_t), B);
2,712✔
614

615
      in += this_loop * BLOCK_SIZE;
2,712✔
616
      out += this_loop * BLOCK_SIZE;
2,712✔
617
      blocks -= this_loop;
2,712✔
618
   }
619
}
2,694✔
620

621
inline uint32_t xtime32(uint32_t s) {
188,808✔
622
   const uint32_t lo_bit = 0x01010101;
188,808✔
623
   const uint32_t mask = 0x7F7F7F7F;
188,808✔
624
   const uint32_t poly = 0x1B;
188,808✔
625

626
   return ((s & mask) << 1) ^ (((s >> 7) & lo_bit) * poly);
188,808✔
627
}
628

629
inline uint32_t InvMixColumn(uint32_t s1) {
188,808✔
630
   const uint32_t s2 = xtime32(s1);
188,808✔
631
   const uint32_t s4 = xtime32(s2);
188,808✔
632
   const uint32_t s8 = xtime32(s4);
188,808✔
633
   const uint32_t s9 = s8 ^ s1;
188,808✔
634
   const uint32_t s11 = s9 ^ s2;
188,808✔
635
   const uint32_t s13 = s9 ^ s4;
188,808✔
636
   const uint32_t s14 = s8 ^ s4 ^ s2;
188,808✔
637

638
   return s14 ^ rotr<8>(s9) ^ rotr<16>(s13) ^ rotr<24>(s11);
188,808✔
639
}
640

641
void InvMixColumn_x4(uint32_t x[4]) {
47,202✔
642
   x[0] = InvMixColumn(x[0]);
47,202✔
643
   x[1] = InvMixColumn(x[1]);
47,202✔
644
   x[2] = InvMixColumn(x[2]);
47,202✔
645
   x[3] = InvMixColumn(x[3]);
47,202✔
646
}
47,202✔
647

648
uint32_t SE_word(uint32_t x) {
44,264✔
649
   uint32_t I[8] = {0};
44,264✔
650

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

655
   AES_SBOX(I);
44,264✔
656

657
   x = 0;
44,264✔
658

659
   for(size_t i = 0; i != 8; ++i) {
398,376✔
660
      x |= ((I[i] & 0x01010101) << (7 - i));
354,112✔
661
   }
662

663
   return x;
44,264✔
664
}
665

666
void aes_key_schedule(const uint8_t key[],
4,226✔
667
                      size_t length,
668
                      secure_vector<uint32_t>& EK,
669
                      secure_vector<uint32_t>& DK,
670
                      bool bswap_keys = false) {
671
   static const uint32_t RC[10] = {0x01000000,
4,226✔
672
                                   0x02000000,
673
                                   0x04000000,
674
                                   0x08000000,
675
                                   0x10000000,
676
                                   0x20000000,
677
                                   0x40000000,
678
                                   0x80000000,
679
                                   0x1B000000,
680
                                   0x36000000};
681

682
   const size_t X = length / 4;
4,226✔
683

684
   // Can't happen, but make static analyzers happy
685
   BOTAN_ASSERT_NOMSG(X == 4 || X == 6 || X == 8);
4,226✔
686

687
   const size_t rounds = (length / 4) + 6;
4,226✔
688

689
   // Help the optimizer
690
   BOTAN_ASSERT_NOMSG(rounds == 10 || rounds == 12 || rounds == 14);
4,226✔
691

692
   CT::poison(key, length);
4,226✔
693

694
   EK.resize(length + 28);
4,226✔
695
   DK.resize(length + 28);
4,226✔
696

697
   for(size_t i = 0; i != X; ++i) {
30,298✔
698
      EK[i] = load_be<uint32_t>(key, i);
26,072✔
699
   }
700

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

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

707
         if(X == 8 && j == 4) {
161,856✔
708
            EK[i + j] ^= SE_word(EK[i + j - 1]);
9,576✔
709
         } else {
710
            EK[i + j] ^= EK[i + j - 1];
152,280✔
711
         }
712
      }
713
   }
714

715
   for(size_t i = 0; i != 4 * (rounds + 1); i += 4) {
59,880✔
716
      DK[i] = EK[4 * rounds - i];
55,654✔
717
      DK[i + 1] = EK[4 * rounds - i + 1];
55,654✔
718
      DK[i + 2] = EK[4 * rounds - i + 2];
55,654✔
719
      DK[i + 3] = EK[4 * rounds - i + 3];
55,654✔
720
   }
721

722
   for(size_t i = 4; i != 4 * rounds; i += 4) {
51,428✔
723
      InvMixColumn_x4(&DK[i]);
47,202✔
724
   }
725

726
   if(bswap_keys) {
4,226✔
727
      // HW AES on little endian needs the subkeys to be byte reversed
728
      for(size_t i = 0; i != EK.size(); ++i) {
×
729
         EK[i] = reverse_bytes(EK[i]);
×
730
      }
731
      for(size_t i = 0; i != DK.size(); ++i) {
×
732
         DK[i] = reverse_bytes(DK[i]);
×
733
      }
734
   }
735

736
   CT::unpoison(EK.data(), EK.size());
4,226✔
737
   CT::unpoison(DK.data(), DK.size());
4,226✔
738
   CT::unpoison(key, length);
4,226✔
739
}
4,226✔
740

741
size_t aes_parallelism() {
212,367✔
742
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
743
   if(CPUID::has_hw_aes()) {
212,367✔
744
      return 4;  // pipelined
745
   }
746
#endif
747

748
#if defined(BOTAN_HAS_AES_VPERM)
749
   if(CPUID::has_vperm()) {
9,114✔
750
      return 2;  // pipelined
751
   }
752
#endif
753

754
   // bitsliced:
755
   return 2;
756
}
757

758
const char* aes_provider() {
4,041✔
759
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
760
   if(CPUID::has_hw_aes()) {
4,041✔
761
      return "cpu";
762
   }
763
#endif
764

765
#if defined(BOTAN_HAS_AES_VPERM)
766
   if(CPUID::has_vperm()) {
2,694✔
767
      return "vperm";
1,347✔
768
   }
769
#endif
770

771
   return "base";
772
}
773

774
}  // namespace
775

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

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

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

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

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

786
size_t AES_256::parallelism() const { return aes_parallelism(); }
194,656✔
787

788
bool AES_128::has_keying_material() const { return !m_EK.empty(); }
221,306✔
789

790
bool AES_192::has_keying_material() const { return !m_EK.empty(); }
53,326✔
791

792
bool AES_256::has_keying_material() const { return !m_EK.empty(); }
983,685✔
793

794
void AES_128::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
144,660✔
795
   assert_key_material_set();
144,660✔
796

797
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
798
   if(CPUID::has_hw_aes()) {
139,731✔
799
      return hw_aes_encrypt_n(in, out, blocks);
136,029✔
800
   }
801
#endif
802

803
#if defined(BOTAN_HAS_AES_VPERM)
804
   if(CPUID::has_vperm()) {
3,702✔
805
      return vperm_encrypt_n(in, out, blocks);
2,085✔
806
   }
807
#endif
808

809
   aes_encrypt_n(in, out, blocks, m_EK);
1,617✔
810
}
811

812
void AES_128::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
21,037✔
813
   assert_key_material_set();
21,037✔
814

815
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
816
   if(CPUID::has_hw_aes()) {
18,738✔
817
      return hw_aes_decrypt_n(in, out, blocks);
17,206✔
818
   }
819
#endif
820

821
#if defined(BOTAN_HAS_AES_VPERM)
822
   if(CPUID::has_vperm()) {
1,532✔
823
      return vperm_decrypt_n(in, out, blocks);
766✔
824
   }
825
#endif
826

827
   aes_decrypt_n(in, out, blocks, m_DK);
766✔
828
}
829

830
void AES_128::key_schedule(const uint8_t key[], size_t length) {
11,223✔
831
#if defined(BOTAN_HAS_AES_NI)
832
   if(CPUID::has_aes_ni()) {
11,223✔
833
      return aesni_key_schedule(key, length);
8,658✔
834
   }
835
#endif
836

837
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
838
   if(CPUID::has_hw_aes()) {
2,565✔
839
      return aes_key_schedule(key, length, m_EK, m_DK, CPUID::is_little_endian());
×
840
   }
841
#endif
842

843
#if defined(BOTAN_HAS_AES_VPERM)
844
   if(CPUID::has_vperm()) {
2,565✔
845
      return vperm_key_schedule(key, length);
1,327✔
846
   }
847
#endif
848

849
   aes_key_schedule(key, length, m_EK, m_DK);
1,238✔
850
}
851

852
void AES_128::clear() {
7,076✔
853
   zap(m_EK);
7,076✔
854
   zap(m_DK);
7,076✔
855
}
7,076✔
856

857
void AES_192::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
29,406✔
858
   assert_key_material_set();
29,406✔
859

860
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
861
   if(CPUID::has_hw_aes()) {
26,654✔
862
      return hw_aes_encrypt_n(in, out, blocks);
23,375✔
863
   }
864
#endif
865

866
#if defined(BOTAN_HAS_AES_VPERM)
867
   if(CPUID::has_vperm()) {
3,279✔
868
      return vperm_encrypt_n(in, out, blocks);
1,736✔
869
   }
870
#endif
871

872
   aes_encrypt_n(in, out, blocks, m_EK);
1,543✔
873
}
874

875
void AES_192::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
6,162✔
876
   assert_key_material_set();
6,162✔
877

878
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
879
   if(CPUID::has_hw_aes()) {
3,462✔
880
      return hw_aes_decrypt_n(in, out, blocks);
1,662✔
881
   }
882
#endif
883

884
#if defined(BOTAN_HAS_AES_VPERM)
885
   if(CPUID::has_vperm()) {
1,800✔
886
      return vperm_decrypt_n(in, out, blocks);
900✔
887
   }
888
#endif
889

890
   aes_decrypt_n(in, out, blocks, m_DK);
900✔
891
}
892

893
void AES_192::key_schedule(const uint8_t key[], size_t length) {
4,633✔
894
#if defined(BOTAN_HAS_AES_NI)
895
   if(CPUID::has_aes_ni()) {
4,633✔
896
      return aesni_key_schedule(key, length);
1,807✔
897
   }
898
#endif
899

900
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
901
   if(CPUID::has_hw_aes()) {
2,826✔
902
      return aes_key_schedule(key, length, m_EK, m_DK, CPUID::is_little_endian());
×
903
   }
904
#endif
905

906
#if defined(BOTAN_HAS_AES_VPERM)
907
   if(CPUID::has_vperm()) {
2,826✔
908
      return vperm_key_schedule(key, length);
1,434✔
909
   }
910
#endif
911

912
   aes_key_schedule(key, length, m_EK, m_DK);
1,392✔
913
}
914

915
void AES_192::clear() {
3,164✔
916
   zap(m_EK);
3,164✔
917
   zap(m_DK);
3,164✔
918
}
3,164✔
919

920
void AES_256::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
597,667✔
921
   assert_key_material_set();
597,667✔
922

923
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
924
   if(CPUID::has_hw_aes()) {
594,522✔
925
      return hw_aes_encrypt_n(in, out, blocks);
590,553✔
926
   }
927
#endif
928

929
#if defined(BOTAN_HAS_AES_VPERM)
930
   if(CPUID::has_vperm()) {
3,969✔
931
      return vperm_encrypt_n(in, out, blocks);
2,132✔
932
   }
933
#endif
934

935
   aes_encrypt_n(in, out, blocks, m_EK);
1,837✔
936
}
937

938
void AES_256::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
11,813✔
939
   assert_key_material_set();
11,813✔
940

941
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
942
   if(CPUID::has_hw_aes()) {
8,725✔
943
      return hw_aes_decrypt_n(in, out, blocks);
6,669✔
944
   }
945
#endif
946

947
#if defined(BOTAN_HAS_AES_VPERM)
948
   if(CPUID::has_vperm()) {
2,056✔
949
      return vperm_decrypt_n(in, out, blocks);
1,028✔
950
   }
951
#endif
952

953
   aes_decrypt_n(in, out, blocks, m_DK);
1,028✔
954
}
955

956
void AES_256::key_schedule(const uint8_t key[], size_t length) {
113,078✔
957
#if defined(BOTAN_HAS_AES_NI)
958
   if(CPUID::has_aes_ni()) {
113,078✔
959
      return aesni_key_schedule(key, length);
109,832✔
960
   }
961
#endif
962

963
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
964
   if(CPUID::has_hw_aes()) {
3,246✔
965
      return aes_key_schedule(key, length, m_EK, m_DK, CPUID::is_little_endian());
×
966
   }
967
#endif
968

969
#if defined(BOTAN_HAS_AES_VPERM)
970
   if(CPUID::has_vperm()) {
3,246✔
971
      return vperm_key_schedule(key, length);
1,650✔
972
   }
973
#endif
974

975
   aes_key_schedule(key, length, m_EK, m_DK);
1,596✔
976
}
977

978
void AES_256::clear() {
4,306✔
979
   zap(m_EK);
4,306✔
980
   zap(m_DK);
4,306✔
981
}
4,306✔
982

983
}  // namespace Botan
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