]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/bearssl/src/symcipher/aes_pwr8_ctrcbc.c
MFV: r361597
[FreeBSD/FreeBSD.git] / contrib / bearssl / src / symcipher / aes_pwr8_ctrcbc.c
1 /*
2  * Copyright (c) 2018 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 const br_block_ctrcbc_class *
32 br_aes_pwr8_ctrcbc_get_vtable(void)
33 {
34         return br_aes_pwr8_supported() ? &br_aes_pwr8_ctrcbc_vtable : NULL;
35 }
36
37 /* see bearssl_block.h */
38 void
39 br_aes_pwr8_ctrcbc_init(br_aes_pwr8_ctrcbc_keys *ctx,
40         const void *key, size_t len)
41 {
42         ctx->vtable = &br_aes_pwr8_ctrcbc_vtable;
43         ctx->num_rounds = br_aes_pwr8_keysched(ctx->skey.skni, key, len);
44 }
45
46 /*
47  * Register conventions for CTR + CBC-MAC:
48  *
49  *   AES subkeys are in registers 0 to 10/12/14 (depending on keys size)
50  *   Register v15 contains the byteswap index register (little-endian only)
51  *   Register v16 contains the CTR counter value
52  *   Register v17 contains the CBC-MAC current value
53  *   Registers v18 to v27 are scratch
54  *   Counter increment uses v28, v29 and v30
55  *
56  * For CTR alone:
57  *  
58  *   AES subkeys are in registers 0 to 10/12/14 (depending on keys size)
59  *   Register v15 contains the byteswap index register (little-endian only)
60  *   Registers v16 to v19 contain the CTR counter values (four blocks)
61  *   Registers v20 to v27 are scratch
62  *   Counter increment uses v28, v29 and v30
63  */
64
65 #define LOAD_SUBKEYS_128 \
66                 lxvw4x(32, %[cc], %[sk])   \
67                 addi(%[cc], %[cc], 16)     \
68                 lxvw4x(33, %[cc], %[sk])   \
69                 addi(%[cc], %[cc], 16)     \
70                 lxvw4x(34, %[cc], %[sk])   \
71                 addi(%[cc], %[cc], 16)     \
72                 lxvw4x(35, %[cc], %[sk])   \
73                 addi(%[cc], %[cc], 16)     \
74                 lxvw4x(36, %[cc], %[sk])   \
75                 addi(%[cc], %[cc], 16)     \
76                 lxvw4x(37, %[cc], %[sk])   \
77                 addi(%[cc], %[cc], 16)     \
78                 lxvw4x(38, %[cc], %[sk])   \
79                 addi(%[cc], %[cc], 16)     \
80                 lxvw4x(39, %[cc], %[sk])   \
81                 addi(%[cc], %[cc], 16)     \
82                 lxvw4x(40, %[cc], %[sk])   \
83                 addi(%[cc], %[cc], 16)     \
84                 lxvw4x(41, %[cc], %[sk])   \
85                 addi(%[cc], %[cc], 16)     \
86                 lxvw4x(42, %[cc], %[sk])
87
88 #define LOAD_SUBKEYS_192 \
89                 LOAD_SUBKEYS_128 \
90                 addi(%[cc], %[cc], 16)     \
91                 lxvw4x(43, %[cc], %[sk])   \
92                 addi(%[cc], %[cc], 16)     \
93                 lxvw4x(44, %[cc], %[sk])
94
95 #define LOAD_SUBKEYS_256 \
96                 LOAD_SUBKEYS_192 \
97                 addi(%[cc], %[cc], 16)     \
98                 lxvw4x(45, %[cc], %[sk])   \
99                 addi(%[cc], %[cc], 16)     \
100                 lxvw4x(46, %[cc], %[sk])
101
102 #define BLOCK_ENCRYPT_128(x) \
103                 vxor(x, x, 0) \
104                 vcipher(x, x, 1) \
105                 vcipher(x, x, 2) \
106                 vcipher(x, x, 3) \
107                 vcipher(x, x, 4) \
108                 vcipher(x, x, 5) \
109                 vcipher(x, x, 6) \
110                 vcipher(x, x, 7) \
111                 vcipher(x, x, 8) \
112                 vcipher(x, x, 9) \
113                 vcipherlast(x, x, 10)
114
115 #define BLOCK_ENCRYPT_192(x) \
116                 vxor(x, x, 0) \
117                 vcipher(x, x, 1) \
118                 vcipher(x, x, 2) \
119                 vcipher(x, x, 3) \
120                 vcipher(x, x, 4) \
121                 vcipher(x, x, 5) \
122                 vcipher(x, x, 6) \
123                 vcipher(x, x, 7) \
124                 vcipher(x, x, 8) \
125                 vcipher(x, x, 9) \
126                 vcipher(x, x, 10) \
127                 vcipher(x, x, 11) \
128                 vcipherlast(x, x, 12)
129
130 #define BLOCK_ENCRYPT_256(x) \
131                 vxor(x, x, 0) \
132                 vcipher(x, x, 1) \
133                 vcipher(x, x, 2) \
134                 vcipher(x, x, 3) \
135                 vcipher(x, x, 4) \
136                 vcipher(x, x, 5) \
137                 vcipher(x, x, 6) \
138                 vcipher(x, x, 7) \
139                 vcipher(x, x, 8) \
140                 vcipher(x, x, 9) \
141                 vcipher(x, x, 10) \
142                 vcipher(x, x, 11) \
143                 vcipher(x, x, 12) \
144                 vcipher(x, x, 13) \
145                 vcipherlast(x, x, 14)
146
147 #define BLOCK_ENCRYPT_X2_128(x, y) \
148                 vxor(x, x, 0) \
149                 vxor(y, y, 0) \
150                 vcipher(x, x, 1) \
151                 vcipher(y, y, 1) \
152                 vcipher(x, x, 2) \
153                 vcipher(y, y, 2) \
154                 vcipher(x, x, 3) \
155                 vcipher(y, y, 3) \
156                 vcipher(x, x, 4) \
157                 vcipher(y, y, 4) \
158                 vcipher(x, x, 5) \
159                 vcipher(y, y, 5) \
160                 vcipher(x, x, 6) \
161                 vcipher(y, y, 6) \
162                 vcipher(x, x, 7) \
163                 vcipher(y, y, 7) \
164                 vcipher(x, x, 8) \
165                 vcipher(y, y, 8) \
166                 vcipher(x, x, 9) \
167                 vcipher(y, y, 9) \
168                 vcipherlast(x, x, 10) \
169                 vcipherlast(y, y, 10)
170
171 #define BLOCK_ENCRYPT_X2_192(x, y) \
172                 vxor(x, x, 0) \
173                 vxor(y, y, 0) \
174                 vcipher(x, x, 1) \
175                 vcipher(y, y, 1) \
176                 vcipher(x, x, 2) \
177                 vcipher(y, y, 2) \
178                 vcipher(x, x, 3) \
179                 vcipher(y, y, 3) \
180                 vcipher(x, x, 4) \
181                 vcipher(y, y, 4) \
182                 vcipher(x, x, 5) \
183                 vcipher(y, y, 5) \
184                 vcipher(x, x, 6) \
185                 vcipher(y, y, 6) \
186                 vcipher(x, x, 7) \
187                 vcipher(y, y, 7) \
188                 vcipher(x, x, 8) \
189                 vcipher(y, y, 8) \
190                 vcipher(x, x, 9) \
191                 vcipher(y, y, 9) \
192                 vcipher(x, x, 10) \
193                 vcipher(y, y, 10) \
194                 vcipher(x, x, 11) \
195                 vcipher(y, y, 11) \
196                 vcipherlast(x, x, 12) \
197                 vcipherlast(y, y, 12)
198
199 #define BLOCK_ENCRYPT_X2_256(x, y) \
200                 vxor(x, x, 0) \
201                 vxor(y, y, 0) \
202                 vcipher(x, x, 1) \
203                 vcipher(y, y, 1) \
204                 vcipher(x, x, 2) \
205                 vcipher(y, y, 2) \
206                 vcipher(x, x, 3) \
207                 vcipher(y, y, 3) \
208                 vcipher(x, x, 4) \
209                 vcipher(y, y, 4) \
210                 vcipher(x, x, 5) \
211                 vcipher(y, y, 5) \
212                 vcipher(x, x, 6) \
213                 vcipher(y, y, 6) \
214                 vcipher(x, x, 7) \
215                 vcipher(y, y, 7) \
216                 vcipher(x, x, 8) \
217                 vcipher(y, y, 8) \
218                 vcipher(x, x, 9) \
219                 vcipher(y, y, 9) \
220                 vcipher(x, x, 10) \
221                 vcipher(y, y, 10) \
222                 vcipher(x, x, 11) \
223                 vcipher(y, y, 11) \
224                 vcipher(x, x, 12) \
225                 vcipher(y, y, 12) \
226                 vcipher(x, x, 13) \
227                 vcipher(y, y, 13) \
228                 vcipherlast(x, x, 14) \
229                 vcipherlast(y, y, 14)
230
231 #define BLOCK_ENCRYPT_X4_128(x0, x1, x2, x3) \
232                 vxor(x0, x0, 0) \
233                 vxor(x1, x1, 0) \
234                 vxor(x2, x2, 0) \
235                 vxor(x3, x3, 0) \
236                 vcipher(x0, x0, 1) \
237                 vcipher(x1, x1, 1) \
238                 vcipher(x2, x2, 1) \
239                 vcipher(x3, x3, 1) \
240                 vcipher(x0, x0, 2) \
241                 vcipher(x1, x1, 2) \
242                 vcipher(x2, x2, 2) \
243                 vcipher(x3, x3, 2) \
244                 vcipher(x0, x0, 3) \
245                 vcipher(x1, x1, 3) \
246                 vcipher(x2, x2, 3) \
247                 vcipher(x3, x3, 3) \
248                 vcipher(x0, x0, 4) \
249                 vcipher(x1, x1, 4) \
250                 vcipher(x2, x2, 4) \
251                 vcipher(x3, x3, 4) \
252                 vcipher(x0, x0, 5) \
253                 vcipher(x1, x1, 5) \
254                 vcipher(x2, x2, 5) \
255                 vcipher(x3, x3, 5) \
256                 vcipher(x0, x0, 6) \
257                 vcipher(x1, x1, 6) \
258                 vcipher(x2, x2, 6) \
259                 vcipher(x3, x3, 6) \
260                 vcipher(x0, x0, 7) \
261                 vcipher(x1, x1, 7) \
262                 vcipher(x2, x2, 7) \
263                 vcipher(x3, x3, 7) \
264                 vcipher(x0, x0, 8) \
265                 vcipher(x1, x1, 8) \
266                 vcipher(x2, x2, 8) \
267                 vcipher(x3, x3, 8) \
268                 vcipher(x0, x0, 9) \
269                 vcipher(x1, x1, 9) \
270                 vcipher(x2, x2, 9) \
271                 vcipher(x3, x3, 9) \
272                 vcipherlast(x0, x0, 10) \
273                 vcipherlast(x1, x1, 10) \
274                 vcipherlast(x2, x2, 10) \
275                 vcipherlast(x3, x3, 10)
276
277 #define BLOCK_ENCRYPT_X4_192(x0, x1, x2, x3) \
278                 vxor(x0, x0, 0) \
279                 vxor(x1, x1, 0) \
280                 vxor(x2, x2, 0) \
281                 vxor(x3, x3, 0) \
282                 vcipher(x0, x0, 1) \
283                 vcipher(x1, x1, 1) \
284                 vcipher(x2, x2, 1) \
285                 vcipher(x3, x3, 1) \
286                 vcipher(x0, x0, 2) \
287                 vcipher(x1, x1, 2) \
288                 vcipher(x2, x2, 2) \
289                 vcipher(x3, x3, 2) \
290                 vcipher(x0, x0, 3) \
291                 vcipher(x1, x1, 3) \
292                 vcipher(x2, x2, 3) \
293                 vcipher(x3, x3, 3) \
294                 vcipher(x0, x0, 4) \
295                 vcipher(x1, x1, 4) \
296                 vcipher(x2, x2, 4) \
297                 vcipher(x3, x3, 4) \
298                 vcipher(x0, x0, 5) \
299                 vcipher(x1, x1, 5) \
300                 vcipher(x2, x2, 5) \
301                 vcipher(x3, x3, 5) \
302                 vcipher(x0, x0, 6) \
303                 vcipher(x1, x1, 6) \
304                 vcipher(x2, x2, 6) \
305                 vcipher(x3, x3, 6) \
306                 vcipher(x0, x0, 7) \
307                 vcipher(x1, x1, 7) \
308                 vcipher(x2, x2, 7) \
309                 vcipher(x3, x3, 7) \
310                 vcipher(x0, x0, 8) \
311                 vcipher(x1, x1, 8) \
312                 vcipher(x2, x2, 8) \
313                 vcipher(x3, x3, 8) \
314                 vcipher(x0, x0, 9) \
315                 vcipher(x1, x1, 9) \
316                 vcipher(x2, x2, 9) \
317                 vcipher(x3, x3, 9) \
318                 vcipher(x0, x0, 10) \
319                 vcipher(x1, x1, 10) \
320                 vcipher(x2, x2, 10) \
321                 vcipher(x3, x3, 10) \
322                 vcipher(x0, x0, 11) \
323                 vcipher(x1, x1, 11) \
324                 vcipher(x2, x2, 11) \
325                 vcipher(x3, x3, 11) \
326                 vcipherlast(x0, x0, 12) \
327                 vcipherlast(x1, x1, 12) \
328                 vcipherlast(x2, x2, 12) \
329                 vcipherlast(x3, x3, 12)
330
331 #define BLOCK_ENCRYPT_X4_256(x0, x1, x2, x3) \
332                 vxor(x0, x0, 0) \
333                 vxor(x1, x1, 0) \
334                 vxor(x2, x2, 0) \
335                 vxor(x3, x3, 0) \
336                 vcipher(x0, x0, 1) \
337                 vcipher(x1, x1, 1) \
338                 vcipher(x2, x2, 1) \
339                 vcipher(x3, x3, 1) \
340                 vcipher(x0, x0, 2) \
341                 vcipher(x1, x1, 2) \
342                 vcipher(x2, x2, 2) \
343                 vcipher(x3, x3, 2) \
344                 vcipher(x0, x0, 3) \
345                 vcipher(x1, x1, 3) \
346                 vcipher(x2, x2, 3) \
347                 vcipher(x3, x3, 3) \
348                 vcipher(x0, x0, 4) \
349                 vcipher(x1, x1, 4) \
350                 vcipher(x2, x2, 4) \
351                 vcipher(x3, x3, 4) \
352                 vcipher(x0, x0, 5) \
353                 vcipher(x1, x1, 5) \
354                 vcipher(x2, x2, 5) \
355                 vcipher(x3, x3, 5) \
356                 vcipher(x0, x0, 6) \
357                 vcipher(x1, x1, 6) \
358                 vcipher(x2, x2, 6) \
359                 vcipher(x3, x3, 6) \
360                 vcipher(x0, x0, 7) \
361                 vcipher(x1, x1, 7) \
362                 vcipher(x2, x2, 7) \
363                 vcipher(x3, x3, 7) \
364                 vcipher(x0, x0, 8) \
365                 vcipher(x1, x1, 8) \
366                 vcipher(x2, x2, 8) \
367                 vcipher(x3, x3, 8) \
368                 vcipher(x0, x0, 9) \
369                 vcipher(x1, x1, 9) \
370                 vcipher(x2, x2, 9) \
371                 vcipher(x3, x3, 9) \
372                 vcipher(x0, x0, 10) \
373                 vcipher(x1, x1, 10) \
374                 vcipher(x2, x2, 10) \
375                 vcipher(x3, x3, 10) \
376                 vcipher(x0, x0, 11) \
377                 vcipher(x1, x1, 11) \
378                 vcipher(x2, x2, 11) \
379                 vcipher(x3, x3, 11) \
380                 vcipher(x0, x0, 12) \
381                 vcipher(x1, x1, 12) \
382                 vcipher(x2, x2, 12) \
383                 vcipher(x3, x3, 12) \
384                 vcipher(x0, x0, 13) \
385                 vcipher(x1, x1, 13) \
386                 vcipher(x2, x2, 13) \
387                 vcipher(x3, x3, 13) \
388                 vcipherlast(x0, x0, 14) \
389                 vcipherlast(x1, x1, 14) \
390                 vcipherlast(x2, x2, 14) \
391                 vcipherlast(x3, x3, 14)
392
393 #if BR_POWER8_LE
394 static const uint32_t idx2be[] = {
395         0x03020100, 0x07060504, 0x0B0A0908, 0x0F0E0D0C
396 };
397 #define BYTESWAP_INIT     lxvw4x(47, 0, %[idx2be])
398 #define BYTESWAP(x)       vperm(x, x, x, 15)
399 #define BYTESWAPX(d, s)   vperm(d, s, s, 15)
400 #define BYTESWAP_REG      , [idx2be] "b" (idx2be)
401 #else
402 #define BYTESWAP_INIT
403 #define BYTESWAP(x)
404 #define BYTESWAPX(d, s)   vand(d, s, s)
405 #define BYTESWAP_REG
406 #endif
407
408 static const uint32_t ctrinc[] = {
409         0, 0, 0, 1
410 };
411 static const uint32_t ctrinc_x4[] = {
412         0, 0, 0, 4
413 };
414 #define INCR_128_INIT      lxvw4x(60, 0, %[ctrinc])
415 #define INCR_128_X4_INIT   lxvw4x(60, 0, %[ctrinc_x4])
416 #define INCR_128(d, s) \
417                 vaddcuw(29, s, 28) \
418                 vadduwm(d, s, 28) \
419                 vsldoi(30, 29, 29, 4) \
420                 vaddcuw(29, d, 30) \
421                 vadduwm(d, d, 30) \
422                 vsldoi(30, 29, 29, 4) \
423                 vaddcuw(29, d, 30) \
424                 vadduwm(d, d, 30) \
425                 vsldoi(30, 29, 29, 4) \
426                 vadduwm(d, d, 30)
427
428 #define MKCTR(size) \
429 static void \
430 ctr_ ## size(const unsigned char *sk, \
431         unsigned char *ctrbuf, unsigned char *buf, size_t num_blocks_x4) \
432 { \
433         long cc, cc0, cc1, cc2, cc3; \
434  \
435         cc = 0; \
436         cc0 = 0; \
437         cc1 = 16; \
438         cc2 = 32; \
439         cc3 = 48; \
440         asm volatile ( \
441  \
442                 /* \
443                  * Load subkeys into v0..v10 \
444                  */ \
445                 LOAD_SUBKEYS_ ## size \
446                 li(%[cc], 0) \
447  \
448                 BYTESWAP_INIT \
449                 INCR_128_X4_INIT \
450  \
451                 /* \
452                  * Load current CTR counters into v16 to v19. \
453                  */ \
454                 lxvw4x(48, %[cc0], %[ctrbuf]) \
455                 lxvw4x(49, %[cc1], %[ctrbuf]) \
456                 lxvw4x(50, %[cc2], %[ctrbuf]) \
457                 lxvw4x(51, %[cc3], %[ctrbuf]) \
458                 BYTESWAP(16) \
459                 BYTESWAP(17) \
460                 BYTESWAP(18) \
461                 BYTESWAP(19) \
462  \
463                 mtctr(%[num_blocks_x4]) \
464  \
465         label(loop) \
466                 /* \
467                  * Compute next counter values into v20..v23. \
468                  */ \
469                 INCR_128(20, 16) \
470                 INCR_128(21, 17) \
471                 INCR_128(22, 18) \
472                 INCR_128(23, 19) \
473  \
474                 /* \
475                  * Encrypt counter values and XOR into next data blocks. \
476                  */ \
477                 lxvw4x(56, %[cc0], %[buf]) \
478                 lxvw4x(57, %[cc1], %[buf]) \
479                 lxvw4x(58, %[cc2], %[buf]) \
480                 lxvw4x(59, %[cc3], %[buf]) \
481                 BYTESWAP(24) \
482                 BYTESWAP(25) \
483                 BYTESWAP(26) \
484                 BYTESWAP(27) \
485                 BLOCK_ENCRYPT_X4_ ## size(16, 17, 18, 19) \
486                 vxor(16, 16, 24) \
487                 vxor(17, 17, 25) \
488                 vxor(18, 18, 26) \
489                 vxor(19, 19, 27) \
490                 BYTESWAP(16) \
491                 BYTESWAP(17) \
492                 BYTESWAP(18) \
493                 BYTESWAP(19) \
494                 stxvw4x(48, %[cc0], %[buf]) \
495                 stxvw4x(49, %[cc1], %[buf]) \
496                 stxvw4x(50, %[cc2], %[buf]) \
497                 stxvw4x(51, %[cc3], %[buf]) \
498  \
499                 /* \
500                  * Update counters and data pointer. \
501                  */ \
502                 vand(16, 20, 20) \
503                 vand(17, 21, 21) \
504                 vand(18, 22, 22) \
505                 vand(19, 23, 23) \
506                 addi(%[buf], %[buf], 64) \
507  \
508                 bdnz(loop) \
509  \
510                 /* \
511                  * Write back new counter values. \
512                  */ \
513                 BYTESWAP(16) \
514                 BYTESWAP(17) \
515                 BYTESWAP(18) \
516                 BYTESWAP(19) \
517                 stxvw4x(48, %[cc0], %[ctrbuf]) \
518                 stxvw4x(49, %[cc1], %[ctrbuf]) \
519                 stxvw4x(50, %[cc2], %[ctrbuf]) \
520                 stxvw4x(51, %[cc3], %[ctrbuf]) \
521  \
522 : [cc] "+b" (cc), [buf] "+b" (buf), \
523         [cc0] "+b" (cc0), [cc1] "+b" (cc1), [cc2] "+b" (cc2), [cc3] "+b" (cc3) \
524 : [sk] "b" (sk), [ctrbuf] "b" (ctrbuf), \
525         [num_blocks_x4] "b" (num_blocks_x4), [ctrinc_x4] "b" (ctrinc_x4) \
526         BYTESWAP_REG \
527 : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", \
528   "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", \
529   "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", \
530   "v30", "ctr", "memory" \
531         ); \
532 }
533
534 MKCTR(128)
535 MKCTR(192)
536 MKCTR(256)
537
538 #define MKCBCMAC(size) \
539 static void \
540 cbcmac_ ## size(const unsigned char *sk, \
541         unsigned char *cbcmac, const unsigned char *buf, size_t num_blocks) \
542 { \
543         long cc; \
544  \
545         cc = 0; \
546         asm volatile ( \
547  \
548                 /* \
549                  * Load subkeys into v0..v10 \
550                  */ \
551                 LOAD_SUBKEYS_ ## size \
552                 li(%[cc], 0) \
553  \
554                 BYTESWAP_INIT \
555  \
556                 /* \
557                  * Load current CBC-MAC value into v16. \
558                  */ \
559                 lxvw4x(48, %[cc], %[cbcmac]) \
560                 BYTESWAP(16) \
561  \
562                 mtctr(%[num_blocks]) \
563  \
564         label(loop) \
565                 /* \
566                  * Load next block, XOR into current CBC-MAC value, \
567                  * and then encrypt it. \
568                  */ \
569                 lxvw4x(49, %[cc], %[buf]) \
570                 BYTESWAP(17) \
571                 vxor(16, 16, 17) \
572                 BLOCK_ENCRYPT_ ## size(16) \
573                 addi(%[buf], %[buf], 16) \
574  \
575                 bdnz(loop) \
576  \
577                 /* \
578                  * Write back new CBC-MAC value. \
579                  */ \
580                 BYTESWAP(16) \
581                 stxvw4x(48, %[cc], %[cbcmac]) \
582  \
583 : [cc] "+b" (cc), [buf] "+b" (buf) \
584 : [sk] "b" (sk), [cbcmac] "b" (cbcmac), [num_blocks] "b" (num_blocks) \
585         BYTESWAP_REG \
586 : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", \
587   "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", \
588   "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", \
589   "v30", "ctr", "memory" \
590         ); \
591 }
592
593 MKCBCMAC(128)
594 MKCBCMAC(192)
595 MKCBCMAC(256)
596
597 #define MKENCRYPT(size) \
598 static void \
599 ctrcbc_ ## size ## _encrypt(const unsigned char *sk, \
600         unsigned char *ctr, unsigned char *cbcmac, unsigned char *buf, \
601         size_t num_blocks) \
602 { \
603         long cc; \
604  \
605         cc = 0; \
606         asm volatile ( \
607  \
608                 /* \
609                  * Load subkeys into v0..v10 \
610                  */ \
611                 LOAD_SUBKEYS_ ## size \
612                 li(%[cc], 0) \
613  \
614                 BYTESWAP_INIT \
615                 INCR_128_INIT \
616  \
617                 /* \
618                  * Load current CTR counter into v16, and current \
619                  * CBC-MAC IV into v17. \
620                  */ \
621                 lxvw4x(48, %[cc], %[ctr]) \
622                 lxvw4x(49, %[cc], %[cbcmac]) \
623                 BYTESWAP(16) \
624                 BYTESWAP(17) \
625  \
626                 /* \
627                  * At each iteration, we do two parallel encryption: \
628                  *  - new counter value for encryption of the next block; \
629                  *  - CBC-MAC over the previous encrypted block. \
630                  * Thus, each plaintext block implies two AES instances, \
631                  * over two successive iterations. This requires a single \
632                  * counter encryption before the loop, and a single \
633                  * CBC-MAC encryption after the loop. \
634                  */ \
635  \
636                 /* \
637                  * Encrypt first block (into v20). \
638                  */ \
639                 lxvw4x(52, %[cc], %[buf]) \
640                 BYTESWAP(20) \
641                 INCR_128(22, 16) \
642                 BLOCK_ENCRYPT_ ## size(16) \
643                 vxor(20, 20, 16) \
644                 BYTESWAPX(21, 20) \
645                 stxvw4x(53, %[cc], %[buf]) \
646                 vand(16, 22, 22) \
647                 addi(%[buf], %[buf], 16) \
648  \
649                 /* \
650                  * Load loop counter; skip the loop if there is only \
651                  * one block in total (already handled by the boundary \
652                  * conditions). \
653                  */ \
654                 mtctr(%[num_blocks]) \
655                 bdz(fastexit) \
656  \
657         label(loop) \
658                 /* \
659                  * Upon loop entry: \
660                  *    v16   counter value for next block \
661                  *    v17   current CBC-MAC value \
662                  *    v20   encrypted previous block \
663                  */ \
664                 vxor(17, 17, 20) \
665                 INCR_128(22, 16) \
666                 lxvw4x(52, %[cc], %[buf]) \
667                 BYTESWAP(20) \
668                 BLOCK_ENCRYPT_X2_ ## size(16, 17) \
669                 vxor(20, 20, 16) \
670                 BYTESWAPX(21, 20) \
671                 stxvw4x(53, %[cc], %[buf]) \
672                 addi(%[buf], %[buf], 16) \
673                 vand(16, 22, 22) \
674  \
675                 bdnz(loop) \
676  \
677         label(fastexit) \
678                 vxor(17, 17, 20) \
679                 BLOCK_ENCRYPT_ ## size(17) \
680                 BYTESWAP(16) \
681                 BYTESWAP(17) \
682                 stxvw4x(48, %[cc], %[ctr]) \
683                 stxvw4x(49, %[cc], %[cbcmac]) \
684  \
685 : [cc] "+b" (cc), [buf] "+b" (buf) \
686 : [sk] "b" (sk), [ctr] "b" (ctr), [cbcmac] "b" (cbcmac), \
687         [num_blocks] "b" (num_blocks), [ctrinc] "b" (ctrinc) \
688         BYTESWAP_REG \
689 : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", \
690   "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", \
691   "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", \
692   "v30", "ctr", "memory" \
693         ); \
694 }
695
696 MKENCRYPT(128)
697 MKENCRYPT(192)
698 MKENCRYPT(256)
699
700 #define MKDECRYPT(size) \
701 static void \
702 ctrcbc_ ## size ## _decrypt(const unsigned char *sk, \
703         unsigned char *ctr, unsigned char *cbcmac, unsigned char *buf, \
704         size_t num_blocks) \
705 { \
706         long cc; \
707  \
708         cc = 0; \
709         asm volatile ( \
710  \
711                 /* \
712                  * Load subkeys into v0..v10 \
713                  */ \
714                 LOAD_SUBKEYS_ ## size \
715                 li(%[cc], 0) \
716  \
717                 BYTESWAP_INIT \
718                 INCR_128_INIT \
719  \
720                 /* \
721                  * Load current CTR counter into v16, and current \
722                  * CBC-MAC IV into v17. \
723                  */ \
724                 lxvw4x(48, %[cc], %[ctr]) \
725                 lxvw4x(49, %[cc], %[cbcmac]) \
726                 BYTESWAP(16) \
727                 BYTESWAP(17) \
728  \
729                 /* \
730                  * At each iteration, we do two parallel encryption: \
731                  *  - new counter value for decryption of the next block; \
732                  *  - CBC-MAC over the next encrypted block. \
733                  * Each iteration performs the two AES instances related \
734                  * to the current block; there is thus no need for some \
735                  * extra pre-loop and post-loop work as in encryption. \
736                  */ \
737  \
738                 mtctr(%[num_blocks]) \
739  \
740         label(loop) \
741                 /* \
742                  * Upon loop entry: \
743                  *    v16   counter value for next block \
744                  *    v17   current CBC-MAC value \
745                  */ \
746                 lxvw4x(52, %[cc], %[buf]) \
747                 BYTESWAP(20) \
748                 vxor(17, 17, 20) \
749                 INCR_128(22, 16) \
750                 BLOCK_ENCRYPT_X2_ ## size(16, 17) \
751                 vxor(20, 20, 16) \
752                 BYTESWAPX(21, 20) \
753                 stxvw4x(53, %[cc], %[buf]) \
754                 addi(%[buf], %[buf], 16) \
755                 vand(16, 22, 22) \
756  \
757                 bdnz(loop) \
758  \
759                 /* \
760                  * Store back counter and CBC-MAC value. \
761                  */ \
762                 BYTESWAP(16) \
763                 BYTESWAP(17) \
764                 stxvw4x(48, %[cc], %[ctr]) \
765                 stxvw4x(49, %[cc], %[cbcmac]) \
766  \
767 : [cc] "+b" (cc), [buf] "+b" (buf) \
768 : [sk] "b" (sk), [ctr] "b" (ctr), [cbcmac] "b" (cbcmac), \
769         [num_blocks] "b" (num_blocks), [ctrinc] "b" (ctrinc) \
770         BYTESWAP_REG \
771 : "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", \
772   "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", \
773   "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", \
774   "v30", "ctr", "memory" \
775         ); \
776 }
777
778 MKDECRYPT(128)
779 MKDECRYPT(192)
780 MKDECRYPT(256)
781
782 /* see bearssl_block.h */
783 void
784 br_aes_pwr8_ctrcbc_encrypt(const br_aes_pwr8_ctrcbc_keys *ctx,
785         void *ctr, void *cbcmac, void *data, size_t len)
786 {
787         if (len == 0) {
788                 return;
789         }
790         switch (ctx->num_rounds) {
791         case 10:
792                 ctrcbc_128_encrypt(ctx->skey.skni, ctr, cbcmac, data, len >> 4);
793                 break;
794         case 12:
795                 ctrcbc_192_encrypt(ctx->skey.skni, ctr, cbcmac, data, len >> 4);
796                 break;
797         default:
798                 ctrcbc_256_encrypt(ctx->skey.skni, ctr, cbcmac, data, len >> 4);
799                 break;
800         }
801 }
802
803 /* see bearssl_block.h */
804 void
805 br_aes_pwr8_ctrcbc_decrypt(const br_aes_pwr8_ctrcbc_keys *ctx,
806         void *ctr, void *cbcmac, void *data, size_t len)
807 {
808         if (len == 0) {
809                 return;
810         }
811         switch (ctx->num_rounds) {
812         case 10:
813                 ctrcbc_128_decrypt(ctx->skey.skni, ctr, cbcmac, data, len >> 4);
814                 break;
815         case 12:
816                 ctrcbc_192_decrypt(ctx->skey.skni, ctr, cbcmac, data, len >> 4);
817                 break;
818         default:
819                 ctrcbc_256_decrypt(ctx->skey.skni, ctr, cbcmac, data, len >> 4);
820                 break;
821         }
822 }
823
824 static inline void
825 incr_ctr(void *dst, const void *src)
826 {
827         uint64_t hi, lo;
828
829         hi = br_dec64be(src);
830         lo = br_dec64be((const unsigned char *)src + 8);
831         lo ++;
832         hi += ((lo | -lo) >> 63) ^ (uint64_t)1;
833         br_enc64be(dst, hi);
834         br_enc64be((unsigned char *)dst + 8, lo);
835 }
836
837 /* see bearssl_block.h */
838 void
839 br_aes_pwr8_ctrcbc_ctr(const br_aes_pwr8_ctrcbc_keys *ctx,
840         void *ctr, void *data, size_t len)
841 {
842         unsigned char ctrbuf[64];
843
844         memcpy(ctrbuf, ctr, 16);
845         incr_ctr(ctrbuf + 16, ctrbuf);
846         incr_ctr(ctrbuf + 32, ctrbuf + 16);
847         incr_ctr(ctrbuf + 48, ctrbuf + 32);
848         if (len >= 64) {
849                 switch (ctx->num_rounds) {
850                 case 10:
851                         ctr_128(ctx->skey.skni, ctrbuf, data, len >> 6);
852                         break;
853                 case 12:
854                         ctr_192(ctx->skey.skni, ctrbuf, data, len >> 6);
855                         break;
856                 default:
857                         ctr_256(ctx->skey.skni, ctrbuf, data, len >> 6);
858                         break;
859                 }
860                 data = (unsigned char *)data + (len & ~(size_t)63);
861                 len &= 63;
862         }
863         if (len > 0) {
864                 unsigned char tmp[64];
865
866                 if (len >= 32) {
867                         if (len >= 48) {
868                                 memcpy(ctr, ctrbuf + 48, 16);
869                         } else {
870                                 memcpy(ctr, ctrbuf + 32, 16);
871                         }
872                 } else {
873                         if (len >= 16) {
874                                 memcpy(ctr, ctrbuf + 16, 16);
875                         }
876                 }
877                 memcpy(tmp, data, len);
878                 memset(tmp + len, 0, (sizeof tmp) - len);
879                 switch (ctx->num_rounds) {
880                 case 10:
881                         ctr_128(ctx->skey.skni, ctrbuf, tmp, 1);
882                         break;
883                 case 12:
884                         ctr_192(ctx->skey.skni, ctrbuf, tmp, 1);
885                         break;
886                 default:
887                         ctr_256(ctx->skey.skni, ctrbuf, tmp, 1);
888                         break;
889                 }
890                 memcpy(data, tmp, len);
891         } else {
892                 memcpy(ctr, ctrbuf, 16);
893         }
894 }
895
896 /* see bearssl_block.h */
897 void
898 br_aes_pwr8_ctrcbc_mac(const br_aes_pwr8_ctrcbc_keys *ctx,
899         void *cbcmac, const void *data, size_t len)
900 {
901         if (len > 0) {
902                 switch (ctx->num_rounds) {
903                 case 10:
904                         cbcmac_128(ctx->skey.skni, cbcmac, data, len >> 4);
905                         break;
906                 case 12:
907                         cbcmac_192(ctx->skey.skni, cbcmac, data, len >> 4);
908                         break;
909                 default:
910                         cbcmac_256(ctx->skey.skni, cbcmac, data, len >> 4);
911                         break;
912                 }
913         }
914 }
915
916 /* see bearssl_block.h */
917 const br_block_ctrcbc_class br_aes_pwr8_ctrcbc_vtable = {
918         sizeof(br_aes_pwr8_ctrcbc_keys),
919         16,
920         4,
921         (void (*)(const br_block_ctrcbc_class **, const void *, size_t))
922                 &br_aes_pwr8_ctrcbc_init,
923         (void (*)(const br_block_ctrcbc_class *const *,
924                 void *, void *, void *, size_t))
925                 &br_aes_pwr8_ctrcbc_encrypt,
926         (void (*)(const br_block_ctrcbc_class *const *,
927                 void *, void *, void *, size_t))
928                 &br_aes_pwr8_ctrcbc_decrypt,
929         (void (*)(const br_block_ctrcbc_class *const *,
930                 void *, void *, size_t))
931                 &br_aes_pwr8_ctrcbc_ctr,
932         (void (*)(const br_block_ctrcbc_class *const *,
933                 void *, const void *, size_t))
934                 &br_aes_pwr8_ctrcbc_mac
935 };
936
937 #else
938
939 /* see bearssl_block.h */
940 const br_block_ctrcbc_class *
941 br_aes_pwr8_ctrcbc_get_vtable(void)
942 {
943         return NULL;
944 }
945
946 #endif