]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/bearssl/src/symcipher/aes_pwr8_ctr.c
MFV r353628:
[FreeBSD/FreeBSD.git] / contrib / bearssl / src / symcipher / aes_pwr8_ctr.c
1 /*
2  * Copyright (c) 2017 Thomas Pornin <pornin@bolet.org>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining 
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be 
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24
25 #define BR_POWER_ASM_MACROS   1
26 #include "inner.h"
27
28 #if BR_POWER8
29
30 /* see bearssl_block.h */
31 void
32 br_aes_pwr8_ctr_init(br_aes_pwr8_ctr_keys *ctx,
33         const void *key, size_t len)
34 {
35         ctx->vtable = &br_aes_pwr8_ctr_vtable;
36         ctx->num_rounds = br_aes_pwr8_keysched(ctx->skey.skni, key, len);
37 }
38
39 static void
40 ctr_128(const unsigned char *sk, const unsigned char *ivbuf,
41         unsigned char *buf, size_t num_blocks)
42 {
43         long cc0, cc1, cc2, cc3;
44
45 #if BR_POWER8_LE
46         static const uint32_t idx2be[] = {
47                 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C
48         };
49 #endif
50         static const uint32_t ctrinc[] = {
51                 0, 0, 0, 4
52         };
53
54         cc0 = 0;
55         cc1 = 16;
56         cc2 = 32;
57         cc3 = 48;
58         asm volatile (
59
60                 /*
61                  * Load subkeys into v0..v10
62                  */
63                 lxvw4x(32, %[cc0], %[sk])
64                 addi(%[cc0], %[cc0], 16)
65                 lxvw4x(33, %[cc0], %[sk])
66                 addi(%[cc0], %[cc0], 16)
67                 lxvw4x(34, %[cc0], %[sk])
68                 addi(%[cc0], %[cc0], 16)
69                 lxvw4x(35, %[cc0], %[sk])
70                 addi(%[cc0], %[cc0], 16)
71                 lxvw4x(36, %[cc0], %[sk])
72                 addi(%[cc0], %[cc0], 16)
73                 lxvw4x(37, %[cc0], %[sk])
74                 addi(%[cc0], %[cc0], 16)
75                 lxvw4x(38, %[cc0], %[sk])
76                 addi(%[cc0], %[cc0], 16)
77                 lxvw4x(39, %[cc0], %[sk])
78                 addi(%[cc0], %[cc0], 16)
79                 lxvw4x(40, %[cc0], %[sk])
80                 addi(%[cc0], %[cc0], 16)
81                 lxvw4x(41, %[cc0], %[sk])
82                 addi(%[cc0], %[cc0], 16)
83                 lxvw4x(42, %[cc0], %[sk])
84                 li(%[cc0], 0)
85
86 #if BR_POWER8_LE
87                 /*
88                  * v15 = constant for byteswapping words
89                  */
90                 lxvw4x(47, 0, %[idx2be])
91 #endif
92                 /*
93                  * v28 = increment for IV counter.
94                  */
95                 lxvw4x(60, 0, %[ctrinc])
96
97                 /*
98                  * Load IV into v16..v19
99                  */
100                 lxvw4x(48, %[cc0], %[ivbuf])
101                 lxvw4x(49, %[cc1], %[ivbuf])
102                 lxvw4x(50, %[cc2], %[ivbuf])
103                 lxvw4x(51, %[cc3], %[ivbuf])
104 #if BR_POWER8_LE
105                 vperm(16, 16, 16, 15)
106                 vperm(17, 17, 17, 15)
107                 vperm(18, 18, 18, 15)
108                 vperm(19, 19, 19, 15)
109 #endif
110
111                 mtctr(%[num_blocks])
112         label(loop)
113                 /*
114                  * Compute next IV into v24..v27
115                  */
116                 vadduwm(24, 16, 28)
117                 vadduwm(25, 17, 28)
118                 vadduwm(26, 18, 28)
119                 vadduwm(27, 19, 28)
120
121                 /*
122                  * Load next data blocks. We do this early on but we
123                  * won't need them until IV encryption is done.
124                  */
125                 lxvw4x(52, %[cc0], %[buf])
126                 lxvw4x(53, %[cc1], %[buf])
127                 lxvw4x(54, %[cc2], %[buf])
128                 lxvw4x(55, %[cc3], %[buf])
129
130                 /*
131                  * Encrypt the current IV.
132                  */
133                 vxor(16, 16, 0)
134                 vxor(17, 17, 0)
135                 vxor(18, 18, 0)
136                 vxor(19, 19, 0)
137                 vcipher(16, 16, 1)
138                 vcipher(17, 17, 1)
139                 vcipher(18, 18, 1)
140                 vcipher(19, 19, 1)
141                 vcipher(16, 16, 2)
142                 vcipher(17, 17, 2)
143                 vcipher(18, 18, 2)
144                 vcipher(19, 19, 2)
145                 vcipher(16, 16, 3)
146                 vcipher(17, 17, 3)
147                 vcipher(18, 18, 3)
148                 vcipher(19, 19, 3)
149                 vcipher(16, 16, 4)
150                 vcipher(17, 17, 4)
151                 vcipher(18, 18, 4)
152                 vcipher(19, 19, 4)
153                 vcipher(16, 16, 5)
154                 vcipher(17, 17, 5)
155                 vcipher(18, 18, 5)
156                 vcipher(19, 19, 5)
157                 vcipher(16, 16, 6)
158                 vcipher(17, 17, 6)
159                 vcipher(18, 18, 6)
160                 vcipher(19, 19, 6)
161                 vcipher(16, 16, 7)
162                 vcipher(17, 17, 7)
163                 vcipher(18, 18, 7)
164                 vcipher(19, 19, 7)
165                 vcipher(16, 16, 8)
166                 vcipher(17, 17, 8)
167                 vcipher(18, 18, 8)
168                 vcipher(19, 19, 8)
169                 vcipher(16, 16, 9)
170                 vcipher(17, 17, 9)
171                 vcipher(18, 18, 9)
172                 vcipher(19, 19, 9)
173                 vcipherlast(16, 16, 10)
174                 vcipherlast(17, 17, 10)
175                 vcipherlast(18, 18, 10)
176                 vcipherlast(19, 19, 10)
177
178 #if BR_POWER8_LE
179                 vperm(16, 16, 16, 15)
180                 vperm(17, 17, 17, 15)
181                 vperm(18, 18, 18, 15)
182                 vperm(19, 19, 19, 15)
183 #endif
184
185                 /*
186                  * Load next plaintext word and XOR with encrypted IV.
187                  */
188                 vxor(16, 20, 16)
189                 vxor(17, 21, 17)
190                 vxor(18, 22, 18)
191                 vxor(19, 23, 19)
192                 stxvw4x(48, %[cc0], %[buf])
193                 stxvw4x(49, %[cc1], %[buf])
194                 stxvw4x(50, %[cc2], %[buf])
195                 stxvw4x(51, %[cc3], %[buf])
196
197                 addi(%[buf], %[buf], 64)
198
199                 /*
200                  * Update IV.
201                  */
202                 vand(16, 24, 24)
203                 vand(17, 25, 25)
204                 vand(18, 26, 26)
205                 vand(19, 27, 27)
206
207                 bdnz(loop)
208
209 : [cc0] "+b" (cc0), [cc1] "+b" (cc1), [cc2] "+b" (cc2), [cc3] "+b" (cc3),
210   [buf] "+b" (buf)
211 : [sk] "b" (sk), [ivbuf] "b" (ivbuf), [num_blocks] "b" (num_blocks >> 2),
212   [ctrinc] "b" (ctrinc)
213 #if BR_POWER8_LE
214         , [idx2be] "b" (idx2be)
215 #endif
216 : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9",
217   "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19",
218   "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29",
219   "ctr", "memory"
220         );
221 }
222
223 static void
224 ctr_192(const unsigned char *sk, const unsigned char *ivbuf,
225         unsigned char *buf, size_t num_blocks)
226 {
227         long cc0, cc1, cc2, cc3;
228
229 #if BR_POWER8_LE
230         static const uint32_t idx2be[] = {
231                 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C
232         };
233 #endif
234         static const uint32_t ctrinc[] = {
235                 0, 0, 0, 4
236         };
237
238         cc0 = 0;
239         cc1 = 16;
240         cc2 = 32;
241         cc3 = 48;
242         asm volatile (
243
244                 /*
245                  * Load subkeys into v0..v12
246                  */
247                 lxvw4x(32, %[cc0], %[sk])
248                 addi(%[cc0], %[cc0], 16)
249                 lxvw4x(33, %[cc0], %[sk])
250                 addi(%[cc0], %[cc0], 16)
251                 lxvw4x(34, %[cc0], %[sk])
252                 addi(%[cc0], %[cc0], 16)
253                 lxvw4x(35, %[cc0], %[sk])
254                 addi(%[cc0], %[cc0], 16)
255                 lxvw4x(36, %[cc0], %[sk])
256                 addi(%[cc0], %[cc0], 16)
257                 lxvw4x(37, %[cc0], %[sk])
258                 addi(%[cc0], %[cc0], 16)
259                 lxvw4x(38, %[cc0], %[sk])
260                 addi(%[cc0], %[cc0], 16)
261                 lxvw4x(39, %[cc0], %[sk])
262                 addi(%[cc0], %[cc0], 16)
263                 lxvw4x(40, %[cc0], %[sk])
264                 addi(%[cc0], %[cc0], 16)
265                 lxvw4x(41, %[cc0], %[sk])
266                 addi(%[cc0], %[cc0], 16)
267                 lxvw4x(42, %[cc0], %[sk])
268                 addi(%[cc0], %[cc0], 16)
269                 lxvw4x(43, %[cc0], %[sk])
270                 addi(%[cc0], %[cc0], 16)
271                 lxvw4x(44, %[cc0], %[sk])
272                 li(%[cc0], 0)
273
274 #if BR_POWER8_LE
275                 /*
276                  * v15 = constant for byteswapping words
277                  */
278                 lxvw4x(47, 0, %[idx2be])
279 #endif
280                 /*
281                  * v28 = increment for IV counter.
282                  */
283                 lxvw4x(60, 0, %[ctrinc])
284
285                 /*
286                  * Load IV into v16..v19
287                  */
288                 lxvw4x(48, %[cc0], %[ivbuf])
289                 lxvw4x(49, %[cc1], %[ivbuf])
290                 lxvw4x(50, %[cc2], %[ivbuf])
291                 lxvw4x(51, %[cc3], %[ivbuf])
292 #if BR_POWER8_LE
293                 vperm(16, 16, 16, 15)
294                 vperm(17, 17, 17, 15)
295                 vperm(18, 18, 18, 15)
296                 vperm(19, 19, 19, 15)
297 #endif
298
299                 mtctr(%[num_blocks])
300         label(loop)
301                 /*
302                  * Compute next IV into v24..v27
303                  */
304                 vadduwm(24, 16, 28)
305                 vadduwm(25, 17, 28)
306                 vadduwm(26, 18, 28)
307                 vadduwm(27, 19, 28)
308
309                 /*
310                  * Load next data blocks. We do this early on but we
311                  * won't need them until IV encryption is done.
312                  */
313                 lxvw4x(52, %[cc0], %[buf])
314                 lxvw4x(53, %[cc1], %[buf])
315                 lxvw4x(54, %[cc2], %[buf])
316                 lxvw4x(55, %[cc3], %[buf])
317
318                 /*
319                  * Encrypt the current IV.
320                  */
321                 vxor(16, 16, 0)
322                 vxor(17, 17, 0)
323                 vxor(18, 18, 0)
324                 vxor(19, 19, 0)
325                 vcipher(16, 16, 1)
326                 vcipher(17, 17, 1)
327                 vcipher(18, 18, 1)
328                 vcipher(19, 19, 1)
329                 vcipher(16, 16, 2)
330                 vcipher(17, 17, 2)
331                 vcipher(18, 18, 2)
332                 vcipher(19, 19, 2)
333                 vcipher(16, 16, 3)
334                 vcipher(17, 17, 3)
335                 vcipher(18, 18, 3)
336                 vcipher(19, 19, 3)
337                 vcipher(16, 16, 4)
338                 vcipher(17, 17, 4)
339                 vcipher(18, 18, 4)
340                 vcipher(19, 19, 4)
341                 vcipher(16, 16, 5)
342                 vcipher(17, 17, 5)
343                 vcipher(18, 18, 5)
344                 vcipher(19, 19, 5)
345                 vcipher(16, 16, 6)
346                 vcipher(17, 17, 6)
347                 vcipher(18, 18, 6)
348                 vcipher(19, 19, 6)
349                 vcipher(16, 16, 7)
350                 vcipher(17, 17, 7)
351                 vcipher(18, 18, 7)
352                 vcipher(19, 19, 7)
353                 vcipher(16, 16, 8)
354                 vcipher(17, 17, 8)
355                 vcipher(18, 18, 8)
356                 vcipher(19, 19, 8)
357                 vcipher(16, 16, 9)
358                 vcipher(17, 17, 9)
359                 vcipher(18, 18, 9)
360                 vcipher(19, 19, 9)
361                 vcipher(16, 16, 10)
362                 vcipher(17, 17, 10)
363                 vcipher(18, 18, 10)
364                 vcipher(19, 19, 10)
365                 vcipher(16, 16, 11)
366                 vcipher(17, 17, 11)
367                 vcipher(18, 18, 11)
368                 vcipher(19, 19, 11)
369                 vcipherlast(16, 16, 12)
370                 vcipherlast(17, 17, 12)
371                 vcipherlast(18, 18, 12)
372                 vcipherlast(19, 19, 12)
373
374 #if BR_POWER8_LE
375                 vperm(16, 16, 16, 15)
376                 vperm(17, 17, 17, 15)
377                 vperm(18, 18, 18, 15)
378                 vperm(19, 19, 19, 15)
379 #endif
380
381                 /*
382                  * Load next plaintext word and XOR with encrypted IV.
383                  */
384                 vxor(16, 20, 16)
385                 vxor(17, 21, 17)
386                 vxor(18, 22, 18)
387                 vxor(19, 23, 19)
388                 stxvw4x(48, %[cc0], %[buf])
389                 stxvw4x(49, %[cc1], %[buf])
390                 stxvw4x(50, %[cc2], %[buf])
391                 stxvw4x(51, %[cc3], %[buf])
392
393                 addi(%[buf], %[buf], 64)
394
395                 /*
396                  * Update IV.
397                  */
398                 vand(16, 24, 24)
399                 vand(17, 25, 25)
400                 vand(18, 26, 26)
401                 vand(19, 27, 27)
402
403                 bdnz(loop)
404
405 : [cc0] "+b" (cc0), [cc1] "+b" (cc1), [cc2] "+b" (cc2), [cc3] "+b" (cc3),
406   [buf] "+b" (buf)
407 : [sk] "b" (sk), [ivbuf] "b" (ivbuf), [num_blocks] "b" (num_blocks >> 2),
408   [ctrinc] "b" (ctrinc)
409 #if BR_POWER8_LE
410         , [idx2be] "b" (idx2be)
411 #endif
412 : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9",
413   "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19",
414   "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29",
415   "ctr", "memory"
416         );
417 }
418
419 static void
420 ctr_256(const unsigned char *sk, const unsigned char *ivbuf,
421         unsigned char *buf, size_t num_blocks)
422 {
423         long cc0, cc1, cc2, cc3;
424
425 #if BR_POWER8_LE
426         static const uint32_t idx2be[] = {
427                 0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C
428         };
429 #endif
430         static const uint32_t ctrinc[] = {
431                 0, 0, 0, 4
432         };
433
434         cc0 = 0;
435         cc1 = 16;
436         cc2 = 32;
437         cc3 = 48;
438         asm volatile (
439
440                 /*
441                  * Load subkeys into v0..v14
442                  */
443                 lxvw4x(32, %[cc0], %[sk])
444                 addi(%[cc0], %[cc0], 16)
445                 lxvw4x(33, %[cc0], %[sk])
446                 addi(%[cc0], %[cc0], 16)
447                 lxvw4x(34, %[cc0], %[sk])
448                 addi(%[cc0], %[cc0], 16)
449                 lxvw4x(35, %[cc0], %[sk])
450                 addi(%[cc0], %[cc0], 16)
451                 lxvw4x(36, %[cc0], %[sk])
452                 addi(%[cc0], %[cc0], 16)
453                 lxvw4x(37, %[cc0], %[sk])
454                 addi(%[cc0], %[cc0], 16)
455                 lxvw4x(38, %[cc0], %[sk])
456                 addi(%[cc0], %[cc0], 16)
457                 lxvw4x(39, %[cc0], %[sk])
458                 addi(%[cc0], %[cc0], 16)
459                 lxvw4x(40, %[cc0], %[sk])
460                 addi(%[cc0], %[cc0], 16)
461                 lxvw4x(41, %[cc0], %[sk])
462                 addi(%[cc0], %[cc0], 16)
463                 lxvw4x(42, %[cc0], %[sk])
464                 addi(%[cc0], %[cc0], 16)
465                 lxvw4x(43, %[cc0], %[sk])
466                 addi(%[cc0], %[cc0], 16)
467                 lxvw4x(44, %[cc0], %[sk])
468                 addi(%[cc0], %[cc0], 16)
469                 lxvw4x(45, %[cc0], %[sk])
470                 addi(%[cc0], %[cc0], 16)
471                 lxvw4x(46, %[cc0], %[sk])
472                 li(%[cc0], 0)
473
474 #if BR_POWER8_LE
475                 /*
476                  * v15 = constant for byteswapping words
477                  */
478                 lxvw4x(47, 0, %[idx2be])
479 #endif
480                 /*
481                  * v28 = increment for IV counter.
482                  */
483                 lxvw4x(60, 0, %[ctrinc])
484
485                 /*
486                  * Load IV into v16..v19
487                  */
488                 lxvw4x(48, %[cc0], %[ivbuf])
489                 lxvw4x(49, %[cc1], %[ivbuf])
490                 lxvw4x(50, %[cc2], %[ivbuf])
491                 lxvw4x(51, %[cc3], %[ivbuf])
492 #if BR_POWER8_LE
493                 vperm(16, 16, 16, 15)
494                 vperm(17, 17, 17, 15)
495                 vperm(18, 18, 18, 15)
496                 vperm(19, 19, 19, 15)
497 #endif
498
499                 mtctr(%[num_blocks])
500         label(loop)
501                 /*
502                  * Compute next IV into v24..v27
503                  */
504                 vadduwm(24, 16, 28)
505                 vadduwm(25, 17, 28)
506                 vadduwm(26, 18, 28)
507                 vadduwm(27, 19, 28)
508
509                 /*
510                  * Load next data blocks. We do this early on but we
511                  * won't need them until IV encryption is done.
512                  */
513                 lxvw4x(52, %[cc0], %[buf])
514                 lxvw4x(53, %[cc1], %[buf])
515                 lxvw4x(54, %[cc2], %[buf])
516                 lxvw4x(55, %[cc3], %[buf])
517
518                 /*
519                  * Encrypt the current IV.
520                  */
521                 vxor(16, 16, 0)
522                 vxor(17, 17, 0)
523                 vxor(18, 18, 0)
524                 vxor(19, 19, 0)
525                 vcipher(16, 16, 1)
526                 vcipher(17, 17, 1)
527                 vcipher(18, 18, 1)
528                 vcipher(19, 19, 1)
529                 vcipher(16, 16, 2)
530                 vcipher(17, 17, 2)
531                 vcipher(18, 18, 2)
532                 vcipher(19, 19, 2)
533                 vcipher(16, 16, 3)
534                 vcipher(17, 17, 3)
535                 vcipher(18, 18, 3)
536                 vcipher(19, 19, 3)
537                 vcipher(16, 16, 4)
538                 vcipher(17, 17, 4)
539                 vcipher(18, 18, 4)
540                 vcipher(19, 19, 4)
541                 vcipher(16, 16, 5)
542                 vcipher(17, 17, 5)
543                 vcipher(18, 18, 5)
544                 vcipher(19, 19, 5)
545                 vcipher(16, 16, 6)
546                 vcipher(17, 17, 6)
547                 vcipher(18, 18, 6)
548                 vcipher(19, 19, 6)
549                 vcipher(16, 16, 7)
550                 vcipher(17, 17, 7)
551                 vcipher(18, 18, 7)
552                 vcipher(19, 19, 7)
553                 vcipher(16, 16, 8)
554                 vcipher(17, 17, 8)
555                 vcipher(18, 18, 8)
556                 vcipher(19, 19, 8)
557                 vcipher(16, 16, 9)
558                 vcipher(17, 17, 9)
559                 vcipher(18, 18, 9)
560                 vcipher(19, 19, 9)
561                 vcipher(16, 16, 10)
562                 vcipher(17, 17, 10)
563                 vcipher(18, 18, 10)
564                 vcipher(19, 19, 10)
565                 vcipher(16, 16, 11)
566                 vcipher(17, 17, 11)
567                 vcipher(18, 18, 11)
568                 vcipher(19, 19, 11)
569                 vcipher(16, 16, 12)
570                 vcipher(17, 17, 12)
571                 vcipher(18, 18, 12)
572                 vcipher(19, 19, 12)
573                 vcipher(16, 16, 13)
574                 vcipher(17, 17, 13)
575                 vcipher(18, 18, 13)
576                 vcipher(19, 19, 13)
577                 vcipherlast(16, 16, 14)
578                 vcipherlast(17, 17, 14)
579                 vcipherlast(18, 18, 14)
580                 vcipherlast(19, 19, 14)
581
582 #if BR_POWER8_LE
583                 vperm(16, 16, 16, 15)
584                 vperm(17, 17, 17, 15)
585                 vperm(18, 18, 18, 15)
586                 vperm(19, 19, 19, 15)
587 #endif
588
589                 /*
590                  * Load next plaintext word and XOR with encrypted IV.
591                  */
592                 vxor(16, 20, 16)
593                 vxor(17, 21, 17)
594                 vxor(18, 22, 18)
595                 vxor(19, 23, 19)
596                 stxvw4x(48, %[cc0], %[buf])
597                 stxvw4x(49, %[cc1], %[buf])
598                 stxvw4x(50, %[cc2], %[buf])
599                 stxvw4x(51, %[cc3], %[buf])
600
601                 addi(%[buf], %[buf], 64)
602
603                 /*
604                  * Update IV.
605                  */
606                 vand(16, 24, 24)
607                 vand(17, 25, 25)
608                 vand(18, 26, 26)
609                 vand(19, 27, 27)
610
611                 bdnz(loop)
612
613 : [cc0] "+b" (cc0), [cc1] "+b" (cc1), [cc2] "+b" (cc2), [cc3] "+b" (cc3),
614   [buf] "+b" (buf)
615 : [sk] "b" (sk), [ivbuf] "b" (ivbuf), [num_blocks] "b" (num_blocks >> 2),
616   [ctrinc] "b" (ctrinc)
617 #if BR_POWER8_LE
618         , [idx2be] "b" (idx2be)
619 #endif
620 : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9",
621   "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19",
622   "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29",
623   "ctr", "memory"
624         );
625 }
626
627 /* see bearssl_block.h */
628 uint32_t
629 br_aes_pwr8_ctr_run(const br_aes_pwr8_ctr_keys *ctx,
630         const void *iv, uint32_t cc, void *data, size_t len)
631 {
632         unsigned char *buf;
633         unsigned char ivbuf[64];
634
635         buf = data;
636         memcpy(ivbuf +  0, iv, 12);
637         memcpy(ivbuf + 16, iv, 12);
638         memcpy(ivbuf + 32, iv, 12);
639         memcpy(ivbuf + 48, iv, 12);
640         if (len >= 64) {
641                 br_enc32be(ivbuf + 12, cc + 0);
642                 br_enc32be(ivbuf + 28, cc + 1);
643                 br_enc32be(ivbuf + 44, cc + 2);
644                 br_enc32be(ivbuf + 60, cc + 3);
645                 switch (ctx->num_rounds) {
646                 case 10:
647                         ctr_128(ctx->skey.skni, ivbuf, buf,
648                                 (len >> 4) & ~(size_t)3);
649                         break;
650                 case 12:
651                         ctr_192(ctx->skey.skni, ivbuf, buf,
652                                 (len >> 4) & ~(size_t)3);
653                         break;
654                 default:
655                         ctr_256(ctx->skey.skni, ivbuf, buf,
656                                 (len >> 4) & ~(size_t)3);
657                         break;
658                 }
659                 cc += (len >> 4) & ~(size_t)3;
660                 buf += len & ~(size_t)63;
661                 len &= 63;
662         }
663         if (len > 0) {
664                 unsigned char tmp[64];
665
666                 memcpy(tmp, buf, len);
667                 memset(tmp + len, 0, (sizeof tmp) - len);
668                 br_enc32be(ivbuf + 12, cc + 0);
669                 br_enc32be(ivbuf + 28, cc + 1);
670                 br_enc32be(ivbuf + 44, cc + 2);
671                 br_enc32be(ivbuf + 60, cc + 3);
672                 switch (ctx->num_rounds) {
673                 case 10:
674                         ctr_128(ctx->skey.skni, ivbuf, tmp, 4);
675                         break;
676                 case 12:
677                         ctr_192(ctx->skey.skni, ivbuf, tmp, 4);
678                         break;
679                 default:
680                         ctr_256(ctx->skey.skni, ivbuf, tmp, 4);
681                         break;
682                 }
683                 memcpy(buf, tmp, len);
684                 cc += (len + 15) >> 4;
685         }
686         return cc;
687 }
688
689 /* see bearssl_block.h */
690 const br_block_ctr_class br_aes_pwr8_ctr_vtable = {
691         sizeof(br_aes_pwr8_ctr_keys),
692         16,
693         4,
694         (void (*)(const br_block_ctr_class **, const void *, size_t))
695                 &br_aes_pwr8_ctr_init,
696         (uint32_t (*)(const br_block_ctr_class *const *,
697                 const void *, uint32_t, void *, size_t))
698                 &br_aes_pwr8_ctr_run
699 };
700
701 /* see bearssl_block.h */
702 const br_block_ctr_class *
703 br_aes_pwr8_ctr_get_vtable(void)
704 {
705         return br_aes_pwr8_supported() ? &br_aes_pwr8_ctr_vtable : NULL;
706 }
707
708 #else
709
710 /* see bearssl_block.h */
711 const br_block_ctr_class *
712 br_aes_pwr8_ctr_get_vtable(void)
713 {
714         return NULL;
715 }
716
717 #endif