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

randombit / botan / 11087146043

28 Sep 2024 09:28PM UTC coverage: 92.003% (+0.7%) from 91.274%
11087146043

push

github

web-flow
Create terraform.yml

82959 of 90170 relevant lines covered (92.0%)

9376319.11 hits per line

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

98.77
/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/bswap.h>
11
#include <botan/internal/cpuid.h>
12
#include <botan/internal/ct_utils.h>
13
#include <botan/internal/loadstor.h>
14
#include <botan/internal/rotate.h>
15

16
namespace Botan {
17

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

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

61
namespace {
62

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

531
      bit_transpose(B);
7,154✔
532

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

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

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

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

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

554
      copy_out_be(std::span(out, this_loop * 4 * sizeof(uint32_t)), B);
7,154✔
555

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

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

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

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

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

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

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

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

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

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

591
      bit_transpose(B);
2,712✔
592

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

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

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

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

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

614
      copy_out_be(std::span(out, this_loop * 4 * sizeof(uint32_t)), B);
2,712✔
615

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

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

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

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

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

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

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

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

656
   AES_SBOX(I);
44,264✔
657

658
   x = 0;
44,264✔
659

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

664
   return x;
44,264✔
665
}
666

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

772
   return "base";
773
}
774

775
}  // namespace
776

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

781
std::string AES_192::provider() const {
1,350✔
782
   return aes_provider();
1,350✔
783
}
784

785
std::string AES_256::provider() const {
1,542✔
786
   return aes_provider();
1,542✔
787
}
788

789
size_t AES_128::parallelism() const {
13,012✔
790
   return aes_parallelism();
13,012✔
791
}
792

793
size_t AES_192::parallelism() const {
4,840✔
794
   return aes_parallelism();
4,840✔
795
}
796

797
size_t AES_256::parallelism() const {
196,876✔
798
   return aes_parallelism();
196,876✔
799
}
800

801
bool AES_128::has_keying_material() const {
65,137,172✔
802
   return !m_EK.empty();
65,137,172✔
803
}
804

805
bool AES_192::has_keying_material() const {
53,344✔
806
   return !m_EK.empty();
53,344✔
807
}
808

809
bool AES_256::has_keying_material() const {
1,332,474✔
810
   return !m_EK.empty();
1,332,474✔
811
}
812

813
void AES_128::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
65,050,381✔
814
   assert_key_material_set();
65,050,381✔
815

816
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
817
   if(CPUID::has_hw_aes()) {
65,045,452✔
818
      return hw_aes_encrypt_n(in, out, blocks);
65,041,750✔
819
   }
820
#endif
821

822
#if defined(BOTAN_HAS_AES_VPERM)
823
   if(CPUID::has_vperm()) {
3,702✔
824
      return vperm_encrypt_n(in, out, blocks);
2,085✔
825
   }
826
#endif
827

828
   aes_encrypt_n(in, out, blocks, m_EK);
1,617✔
829
}
830

831
void AES_128::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
28,792✔
832
   assert_key_material_set();
28,792✔
833

834
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
835
   if(CPUID::has_hw_aes()) {
26,493✔
836
      return hw_aes_decrypt_n(in, out, blocks);
24,961✔
837
   }
838
#endif
839

840
#if defined(BOTAN_HAS_AES_VPERM)
841
   if(CPUID::has_vperm()) {
1,532✔
842
      return vperm_decrypt_n(in, out, blocks);
766✔
843
   }
844
#endif
845

846
   aes_decrypt_n(in, out, blocks, m_DK);
766✔
847
}
848

849
void AES_128::key_schedule(std::span<const uint8_t> key) {
11,993✔
850
#if defined(BOTAN_HAS_AES_NI)
851
   if(CPUID::has_aes_ni()) {
11,993✔
852
      return aesni_key_schedule(key.data(), key.size());
9,428✔
853
   }
854
#endif
855

856
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
857
   if(CPUID::has_hw_aes()) {
2,565✔
858
      return aes_key_schedule(key.data(), key.size(), m_EK, m_DK, CPUID::is_little_endian());
×
859
   }
860
#endif
861

862
#if defined(BOTAN_HAS_AES_VPERM)
863
   if(CPUID::has_vperm()) {
2,565✔
864
      return vperm_key_schedule(key.data(), key.size());
1,327✔
865
   }
866
#endif
867

868
   aes_key_schedule(key.data(), key.size(), m_EK, m_DK);
1,238✔
869
}
870

871
void AES_128::clear() {
7,101✔
872
   zap(m_EK);
7,101✔
873
   zap(m_DK);
7,101✔
874
}
7,101✔
875

876
void AES_192::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
29,422✔
877
   assert_key_material_set();
29,422✔
878

879
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
880
   if(CPUID::has_hw_aes()) {
26,670✔
881
      return hw_aes_encrypt_n(in, out, blocks);
23,391✔
882
   }
883
#endif
884

885
#if defined(BOTAN_HAS_AES_VPERM)
886
   if(CPUID::has_vperm()) {
3,279✔
887
      return vperm_encrypt_n(in, out, blocks);
1,736✔
888
   }
889
#endif
890

891
   aes_encrypt_n(in, out, blocks, m_EK);
1,543✔
892
}
893

894
void AES_192::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
6,162✔
895
   assert_key_material_set();
6,162✔
896

897
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
898
   if(CPUID::has_hw_aes()) {
3,462✔
899
      return hw_aes_decrypt_n(in, out, blocks);
1,662✔
900
   }
901
#endif
902

903
#if defined(BOTAN_HAS_AES_VPERM)
904
   if(CPUID::has_vperm()) {
1,800✔
905
      return vperm_decrypt_n(in, out, blocks);
900✔
906
   }
907
#endif
908

909
   aes_decrypt_n(in, out, blocks, m_DK);
900✔
910
}
911

912
void AES_192::key_schedule(std::span<const uint8_t> key) {
4,639✔
913
#if defined(BOTAN_HAS_AES_NI)
914
   if(CPUID::has_aes_ni()) {
4,639✔
915
      return aesni_key_schedule(key.data(), key.size());
1,813✔
916
   }
917
#endif
918

919
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
920
   if(CPUID::has_hw_aes()) {
2,826✔
921
      return aes_key_schedule(key.data(), key.size(), m_EK, m_DK, CPUID::is_little_endian());
×
922
   }
923
#endif
924

925
#if defined(BOTAN_HAS_AES_VPERM)
926
   if(CPUID::has_vperm()) {
2,826✔
927
      return vperm_key_schedule(key.data(), key.size());
1,434✔
928
   }
929
#endif
930

931
   aes_key_schedule(key.data(), key.size(), m_EK, m_DK);
1,392✔
932
}
933

934
void AES_192::clear() {
3,170✔
935
   zap(m_EK);
3,170✔
936
   zap(m_DK);
3,170✔
937
}
3,170✔
938

939
void AES_256::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
571,871✔
940
   assert_key_material_set();
571,871✔
941

942
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
943
   if(CPUID::has_hw_aes()) {
568,726✔
944
      return hw_aes_encrypt_n(in, out, blocks);
564,757✔
945
   }
946
#endif
947

948
#if defined(BOTAN_HAS_AES_VPERM)
949
   if(CPUID::has_vperm()) {
3,969✔
950
      return vperm_encrypt_n(in, out, blocks);
2,132✔
951
   }
952
#endif
953

954
   aes_encrypt_n(in, out, blocks, m_EK);
1,837✔
955
}
956

957
void AES_256::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
14,757✔
958
   assert_key_material_set();
14,757✔
959

960
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
961
   if(CPUID::has_hw_aes()) {
11,669✔
962
      return hw_aes_decrypt_n(in, out, blocks);
9,613✔
963
   }
964
#endif
965

966
#if defined(BOTAN_HAS_AES_VPERM)
967
   if(CPUID::has_vperm()) {
2,056✔
968
      return vperm_decrypt_n(in, out, blocks);
1,028✔
969
   }
970
#endif
971

972
   aes_decrypt_n(in, out, blocks, m_DK);
1,028✔
973
}
974

975
void AES_256::key_schedule(std::span<const uint8_t> key) {
109,892✔
976
#if defined(BOTAN_HAS_AES_NI)
977
   if(CPUID::has_aes_ni()) {
109,892✔
978
      return aesni_key_schedule(key.data(), key.size());
106,646✔
979
   }
980
#endif
981

982
#if defined(BOTAN_HAS_HW_AES_SUPPORT)
983
   if(CPUID::has_hw_aes()) {
3,246✔
984
      return aes_key_schedule(key.data(), key.size(), m_EK, m_DK, CPUID::is_little_endian());
×
985
   }
986
#endif
987

988
#if defined(BOTAN_HAS_AES_VPERM)
989
   if(CPUID::has_vperm()) {
3,246✔
990
      return vperm_key_schedule(key.data(), key.size());
1,650✔
991
   }
992
#endif
993

994
   aes_key_schedule(key.data(), key.size(), m_EK, m_DK);
1,596✔
995
}
996

997
void AES_256::clear() {
6,195✔
998
   zap(m_EK);
6,195✔
999
   zap(m_DK);
6,195✔
1000
}
6,195✔
1001

1002
}  // 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