Merge tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
[linux-2.6-microblaze.git] / arch / x86 / crypto / morus1280-avx2-asm.S
1 /*
2  * AVX2 implementation of MORUS-1280
3  *
4  * Copyright (c) 2017-2018 Ondrej Mosnacek <omosnacek@gmail.com>
5  * Copyright (C) 2017-2018 Red Hat, Inc. All rights reserved.
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License version 2 as published
9  * by the Free Software Foundation.
10  */
11
12 #include <linux/linkage.h>
13 #include <asm/frame.h>
14
15 #define SHUFFLE_MASK(i0, i1, i2, i3) \
16         (i0 | (i1 << 2) | (i2 << 4) | (i3 << 6))
17
18 #define MASK1 SHUFFLE_MASK(3, 0, 1, 2)
19 #define MASK2 SHUFFLE_MASK(2, 3, 0, 1)
20 #define MASK3 SHUFFLE_MASK(1, 2, 3, 0)
21
22 #define STATE0          %ymm0
23 #define STATE0_LOW      %xmm0
24 #define STATE1          %ymm1
25 #define STATE2          %ymm2
26 #define STATE3          %ymm3
27 #define STATE4          %ymm4
28 #define KEY             %ymm5
29 #define MSG             %ymm5
30 #define MSG_LOW         %xmm5
31 #define T0              %ymm6
32 #define T0_LOW          %xmm6
33 #define T1              %ymm7
34
35 .section .rodata.cst32.morus1280_const, "aM", @progbits, 32
36 .align 32
37 .Lmorus1280_const:
38         .byte 0x00, 0x01, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0d
39         .byte 0x15, 0x22, 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62
40         .byte 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1
41         .byte 0x20, 0x11, 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd
42
43 .section .rodata.cst32.morus1280_counter, "aM", @progbits, 32
44 .align 32
45 .Lmorus1280_counter:
46         .byte 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
47         .byte 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
48         .byte 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17
49         .byte 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
50
51 .text
52
53 .macro morus1280_round s0, s1, s2, s3, s4, b, w
54         vpand \s1, \s2, T0
55         vpxor T0, \s0, \s0
56         vpxor \s3, \s0, \s0
57         vpsllq $\b, \s0, T0
58         vpsrlq $(64 - \b), \s0, \s0
59         vpxor T0, \s0, \s0
60         vpermq $\w, \s3, \s3
61 .endm
62
63 /*
64  * __morus1280_update: internal ABI
65  * input:
66  *   STATE[0-4] - input state
67  *   MSG        - message block
68  * output:
69  *   STATE[0-4] - output state
70  * changed:
71  *   T0
72  */
73 __morus1280_update:
74         morus1280_round STATE0, STATE1, STATE2, STATE3, STATE4, 13, MASK1
75         vpxor MSG, STATE1, STATE1
76         morus1280_round STATE1, STATE2, STATE3, STATE4, STATE0, 46, MASK2
77         vpxor MSG, STATE2, STATE2
78         morus1280_round STATE2, STATE3, STATE4, STATE0, STATE1, 38, MASK3
79         vpxor MSG, STATE3, STATE3
80         morus1280_round STATE3, STATE4, STATE0, STATE1, STATE2,  7, MASK2
81         vpxor MSG, STATE4, STATE4
82         morus1280_round STATE4, STATE0, STATE1, STATE2, STATE3,  4, MASK1
83         ret
84 ENDPROC(__morus1280_update)
85
86 /*
87  * __morus1280_update_zero: internal ABI
88  * input:
89  *   STATE[0-4] - input state
90  * output:
91  *   STATE[0-4] - output state
92  * changed:
93  *   T0
94  */
95 __morus1280_update_zero:
96         morus1280_round STATE0, STATE1, STATE2, STATE3, STATE4, 13, MASK1
97         morus1280_round STATE1, STATE2, STATE3, STATE4, STATE0, 46, MASK2
98         morus1280_round STATE2, STATE3, STATE4, STATE0, STATE1, 38, MASK3
99         morus1280_round STATE3, STATE4, STATE0, STATE1, STATE2,  7, MASK2
100         morus1280_round STATE4, STATE0, STATE1, STATE2, STATE3,  4, MASK1
101         ret
102 ENDPROC(__morus1280_update_zero)
103
104 /*
105  * __load_partial: internal ABI
106  * input:
107  *   %rsi - src
108  *   %rcx - bytes
109  * output:
110  *   MSG  - message block
111  * changed:
112  *   %r8
113  *   %r9
114  */
115 __load_partial:
116         xor %r9, %r9
117         vpxor MSG, MSG, MSG
118
119         mov %rcx, %r8
120         and $0x1, %r8
121         jz .Lld_partial_1
122
123         mov %rcx, %r8
124         and $0x1E, %r8
125         add %rsi, %r8
126         mov (%r8), %r9b
127
128 .Lld_partial_1:
129         mov %rcx, %r8
130         and $0x2, %r8
131         jz .Lld_partial_2
132
133         mov %rcx, %r8
134         and $0x1C, %r8
135         add %rsi, %r8
136         shl $16, %r9
137         mov (%r8), %r9w
138
139 .Lld_partial_2:
140         mov %rcx, %r8
141         and $0x4, %r8
142         jz .Lld_partial_4
143
144         mov %rcx, %r8
145         and $0x18, %r8
146         add %rsi, %r8
147         shl $32, %r9
148         mov (%r8), %r8d
149         xor %r8, %r9
150
151 .Lld_partial_4:
152         movq %r9, MSG_LOW
153
154         mov %rcx, %r8
155         and $0x8, %r8
156         jz .Lld_partial_8
157
158         mov %rcx, %r8
159         and $0x10, %r8
160         add %rsi, %r8
161         pshufd $MASK2, MSG_LOW, MSG_LOW
162         pinsrq $0, (%r8), MSG_LOW
163
164 .Lld_partial_8:
165         mov %rcx, %r8
166         and $0x10, %r8
167         jz .Lld_partial_16
168
169         vpermq $MASK2, MSG, MSG
170         movdqu (%rsi), MSG_LOW
171
172 .Lld_partial_16:
173         ret
174 ENDPROC(__load_partial)
175
176 /*
177  * __store_partial: internal ABI
178  * input:
179  *   %rdx - dst
180  *   %rcx - bytes
181  * output:
182  *   T0   - message block
183  * changed:
184  *   %r8
185  *   %r9
186  *   %r10
187  */
188 __store_partial:
189         mov %rcx, %r8
190         mov %rdx, %r9
191
192         cmp $16, %r8
193         jl .Lst_partial_16
194
195         movdqu T0_LOW, (%r9)
196         vpermq $MASK2, T0, T0
197
198         sub $16, %r8
199         add $16, %r9
200
201 .Lst_partial_16:
202         movq T0_LOW, %r10
203
204         cmp $8, %r8
205         jl .Lst_partial_8
206
207         mov %r10, (%r9)
208         pextrq $1, T0_LOW, %r10
209
210         sub $8, %r8
211         add $8, %r9
212
213 .Lst_partial_8:
214         cmp $4, %r8
215         jl .Lst_partial_4
216
217         mov %r10d, (%r9)
218         shr $32, %r10
219
220         sub $4, %r8
221         add $4, %r9
222
223 .Lst_partial_4:
224         cmp $2, %r8
225         jl .Lst_partial_2
226
227         mov %r10w, (%r9)
228         shr $16, %r10
229
230         sub $2, %r8
231         add $2, %r9
232
233 .Lst_partial_2:
234         cmp $1, %r8
235         jl .Lst_partial_1
236
237         mov %r10b, (%r9)
238
239 .Lst_partial_1:
240         ret
241 ENDPROC(__store_partial)
242
243 /*
244  * void crypto_morus1280_avx2_init(void *state, const void *key,
245  *                                 const void *iv);
246  */
247 ENTRY(crypto_morus1280_avx2_init)
248         FRAME_BEGIN
249
250         /* load IV: */
251         vpxor STATE0, STATE0, STATE0
252         movdqu (%rdx), STATE0_LOW
253         /* load key: */
254         vmovdqu (%rsi), KEY
255         vmovdqa KEY, STATE1
256         /* load all ones: */
257         vpcmpeqd STATE2, STATE2, STATE2
258         /* load all zeros: */
259         vpxor STATE3, STATE3, STATE3
260         /* load the constant: */
261         vmovdqa .Lmorus1280_const, STATE4
262
263         /* update 16 times with zero: */
264         call __morus1280_update_zero
265         call __morus1280_update_zero
266         call __morus1280_update_zero
267         call __morus1280_update_zero
268         call __morus1280_update_zero
269         call __morus1280_update_zero
270         call __morus1280_update_zero
271         call __morus1280_update_zero
272         call __morus1280_update_zero
273         call __morus1280_update_zero
274         call __morus1280_update_zero
275         call __morus1280_update_zero
276         call __morus1280_update_zero
277         call __morus1280_update_zero
278         call __morus1280_update_zero
279         call __morus1280_update_zero
280
281         /* xor-in the key again after updates: */
282         vpxor KEY, STATE1, STATE1
283
284         /* store the state: */
285         vmovdqu STATE0, (0 * 32)(%rdi)
286         vmovdqu STATE1, (1 * 32)(%rdi)
287         vmovdqu STATE2, (2 * 32)(%rdi)
288         vmovdqu STATE3, (3 * 32)(%rdi)
289         vmovdqu STATE4, (4 * 32)(%rdi)
290
291         FRAME_END
292         ret
293 ENDPROC(crypto_morus1280_avx2_init)
294
295 /*
296  * void crypto_morus1280_avx2_ad(void *state, const void *data,
297  *                               unsigned int length);
298  */
299 ENTRY(crypto_morus1280_avx2_ad)
300         FRAME_BEGIN
301
302         cmp $32, %rdx
303         jb .Lad_out
304
305         /* load the state: */
306         vmovdqu (0 * 32)(%rdi), STATE0
307         vmovdqu (1 * 32)(%rdi), STATE1
308         vmovdqu (2 * 32)(%rdi), STATE2
309         vmovdqu (3 * 32)(%rdi), STATE3
310         vmovdqu (4 * 32)(%rdi), STATE4
311
312         mov %rsi,  %r8
313         and $0x1F, %r8
314         jnz .Lad_u_loop
315
316 .align 4
317 .Lad_a_loop:
318         vmovdqa (%rsi), MSG
319         call __morus1280_update
320         sub $32, %rdx
321         add $32, %rsi
322         cmp $32, %rdx
323         jge .Lad_a_loop
324
325         jmp .Lad_cont
326 .align 4
327 .Lad_u_loop:
328         vmovdqu (%rsi), MSG
329         call __morus1280_update
330         sub $32, %rdx
331         add $32, %rsi
332         cmp $32, %rdx
333         jge .Lad_u_loop
334
335 .Lad_cont:
336         /* store the state: */
337         vmovdqu STATE0, (0 * 32)(%rdi)
338         vmovdqu STATE1, (1 * 32)(%rdi)
339         vmovdqu STATE2, (2 * 32)(%rdi)
340         vmovdqu STATE3, (3 * 32)(%rdi)
341         vmovdqu STATE4, (4 * 32)(%rdi)
342
343 .Lad_out:
344         FRAME_END
345         ret
346 ENDPROC(crypto_morus1280_avx2_ad)
347
348 /*
349  * void crypto_morus1280_avx2_enc(void *state, const void *src, void *dst,
350  *                                unsigned int length);
351  */
352 ENTRY(crypto_morus1280_avx2_enc)
353         FRAME_BEGIN
354
355         cmp $32, %rcx
356         jb .Lenc_out
357
358         /* load the state: */
359         vmovdqu (0 * 32)(%rdi), STATE0
360         vmovdqu (1 * 32)(%rdi), STATE1
361         vmovdqu (2 * 32)(%rdi), STATE2
362         vmovdqu (3 * 32)(%rdi), STATE3
363         vmovdqu (4 * 32)(%rdi), STATE4
364
365         mov %rsi,  %r8
366         or  %rdx,  %r8
367         and $0x1F, %r8
368         jnz .Lenc_u_loop
369
370 .align 4
371 .Lenc_a_loop:
372         vmovdqa (%rsi), MSG
373         vmovdqa MSG, T0
374         vpxor STATE0, T0, T0
375         vpermq $MASK3, STATE1, T1
376         vpxor T1, T0, T0
377         vpand STATE2, STATE3, T1
378         vpxor T1, T0, T0
379         vmovdqa T0, (%rdx)
380
381         call __morus1280_update
382         sub $32, %rcx
383         add $32, %rsi
384         add $32, %rdx
385         cmp $32, %rcx
386         jge .Lenc_a_loop
387
388         jmp .Lenc_cont
389 .align 4
390 .Lenc_u_loop:
391         vmovdqu (%rsi), MSG
392         vmovdqa MSG, T0
393         vpxor STATE0, T0, T0
394         vpermq $MASK3, STATE1, T1
395         vpxor T1, T0, T0
396         vpand STATE2, STATE3, T1
397         vpxor T1, T0, T0
398         vmovdqu T0, (%rdx)
399
400         call __morus1280_update
401         sub $32, %rcx
402         add $32, %rsi
403         add $32, %rdx
404         cmp $32, %rcx
405         jge .Lenc_u_loop
406
407 .Lenc_cont:
408         /* store the state: */
409         vmovdqu STATE0, (0 * 32)(%rdi)
410         vmovdqu STATE1, (1 * 32)(%rdi)
411         vmovdqu STATE2, (2 * 32)(%rdi)
412         vmovdqu STATE3, (3 * 32)(%rdi)
413         vmovdqu STATE4, (4 * 32)(%rdi)
414
415 .Lenc_out:
416         FRAME_END
417         ret
418 ENDPROC(crypto_morus1280_avx2_enc)
419
420 /*
421  * void crypto_morus1280_avx2_enc_tail(void *state, const void *src, void *dst,
422  *                                     unsigned int length);
423  */
424 ENTRY(crypto_morus1280_avx2_enc_tail)
425         FRAME_BEGIN
426
427         /* load the state: */
428         vmovdqu (0 * 32)(%rdi), STATE0
429         vmovdqu (1 * 32)(%rdi), STATE1
430         vmovdqu (2 * 32)(%rdi), STATE2
431         vmovdqu (3 * 32)(%rdi), STATE3
432         vmovdqu (4 * 32)(%rdi), STATE4
433
434         /* encrypt message: */
435         call __load_partial
436
437         vmovdqa MSG, T0
438         vpxor STATE0, T0, T0
439         vpermq $MASK3, STATE1, T1
440         vpxor T1, T0, T0
441         vpand STATE2, STATE3, T1
442         vpxor T1, T0, T0
443
444         call __store_partial
445
446         call __morus1280_update
447
448         /* store the state: */
449         vmovdqu STATE0, (0 * 32)(%rdi)
450         vmovdqu STATE1, (1 * 32)(%rdi)
451         vmovdqu STATE2, (2 * 32)(%rdi)
452         vmovdqu STATE3, (3 * 32)(%rdi)
453         vmovdqu STATE4, (4 * 32)(%rdi)
454
455         FRAME_END
456 ENDPROC(crypto_morus1280_avx2_enc_tail)
457
458 /*
459  * void crypto_morus1280_avx2_dec(void *state, const void *src, void *dst,
460  *                                unsigned int length);
461  */
462 ENTRY(crypto_morus1280_avx2_dec)
463         FRAME_BEGIN
464
465         cmp $32, %rcx
466         jb .Ldec_out
467
468         /* load the state: */
469         vmovdqu (0 * 32)(%rdi), STATE0
470         vmovdqu (1 * 32)(%rdi), STATE1
471         vmovdqu (2 * 32)(%rdi), STATE2
472         vmovdqu (3 * 32)(%rdi), STATE3
473         vmovdqu (4 * 32)(%rdi), STATE4
474
475         mov %rsi,  %r8
476         or  %rdx,  %r8
477         and $0x1F, %r8
478         jnz .Ldec_u_loop
479
480 .align 4
481 .Ldec_a_loop:
482         vmovdqa (%rsi), MSG
483         vpxor STATE0, MSG, MSG
484         vpermq $MASK3, STATE1, T0
485         vpxor T0, MSG, MSG
486         vpand STATE2, STATE3, T0
487         vpxor T0, MSG, MSG
488         vmovdqa MSG, (%rdx)
489
490         call __morus1280_update
491         sub $32, %rcx
492         add $32, %rsi
493         add $32, %rdx
494         cmp $32, %rcx
495         jge .Ldec_a_loop
496
497         jmp .Ldec_cont
498 .align 4
499 .Ldec_u_loop:
500         vmovdqu (%rsi), MSG
501         vpxor STATE0, MSG, MSG
502         vpermq $MASK3, STATE1, T0
503         vpxor T0, MSG, MSG
504         vpand STATE2, STATE3, T0
505         vpxor T0, MSG, MSG
506         vmovdqu MSG, (%rdx)
507
508         call __morus1280_update
509         sub $32, %rcx
510         add $32, %rsi
511         add $32, %rdx
512         cmp $32, %rcx
513         jge .Ldec_u_loop
514
515 .Ldec_cont:
516         /* store the state: */
517         vmovdqu STATE0, (0 * 32)(%rdi)
518         vmovdqu STATE1, (1 * 32)(%rdi)
519         vmovdqu STATE2, (2 * 32)(%rdi)
520         vmovdqu STATE3, (3 * 32)(%rdi)
521         vmovdqu STATE4, (4 * 32)(%rdi)
522
523 .Ldec_out:
524         FRAME_END
525         ret
526 ENDPROC(crypto_morus1280_avx2_dec)
527
528 /*
529  * void crypto_morus1280_avx2_dec_tail(void *state, const void *src, void *dst,
530  *                                     unsigned int length);
531  */
532 ENTRY(crypto_morus1280_avx2_dec_tail)
533         FRAME_BEGIN
534
535         /* load the state: */
536         vmovdqu (0 * 32)(%rdi), STATE0
537         vmovdqu (1 * 32)(%rdi), STATE1
538         vmovdqu (2 * 32)(%rdi), STATE2
539         vmovdqu (3 * 32)(%rdi), STATE3
540         vmovdqu (4 * 32)(%rdi), STATE4
541
542         /* decrypt message: */
543         call __load_partial
544
545         vpxor STATE0, MSG, MSG
546         vpermq $MASK3, STATE1, T0
547         vpxor T0, MSG, MSG
548         vpand STATE2, STATE3, T0
549         vpxor T0, MSG, MSG
550         vmovdqa MSG, T0
551
552         call __store_partial
553
554         /* mask with byte count: */
555         movq %rcx, T0_LOW
556         vpbroadcastb T0_LOW, T0
557         vmovdqa .Lmorus1280_counter, T1
558         vpcmpgtb T1, T0, T0
559         vpand T0, MSG, MSG
560
561         call __morus1280_update
562
563         /* store the state: */
564         vmovdqu STATE0, (0 * 32)(%rdi)
565         vmovdqu STATE1, (1 * 32)(%rdi)
566         vmovdqu STATE2, (2 * 32)(%rdi)
567         vmovdqu STATE3, (3 * 32)(%rdi)
568         vmovdqu STATE4, (4 * 32)(%rdi)
569
570         FRAME_END
571         ret
572 ENDPROC(crypto_morus1280_avx2_dec_tail)
573
574 /*
575  * void crypto_morus1280_avx2_final(void *state, void *tag_xor,
576  *                                  u64 assoclen, u64 cryptlen);
577  */
578 ENTRY(crypto_morus1280_avx2_final)
579         FRAME_BEGIN
580
581         /* load the state: */
582         vmovdqu (0 * 32)(%rdi), STATE0
583         vmovdqu (1 * 32)(%rdi), STATE1
584         vmovdqu (2 * 32)(%rdi), STATE2
585         vmovdqu (3 * 32)(%rdi), STATE3
586         vmovdqu (4 * 32)(%rdi), STATE4
587
588         /* xor state[0] into state[4]: */
589         vpxor STATE0, STATE4, STATE4
590
591         /* prepare length block: */
592         vpxor MSG, MSG, MSG
593         vpinsrq $0, %rdx, MSG_LOW, MSG_LOW
594         vpinsrq $1, %rcx, MSG_LOW, MSG_LOW
595         vpsllq $3, MSG, MSG /* multiply by 8 (to get bit count) */
596
597         /* update state: */
598         call __morus1280_update
599         call __morus1280_update
600         call __morus1280_update
601         call __morus1280_update
602         call __morus1280_update
603         call __morus1280_update
604         call __morus1280_update
605         call __morus1280_update
606         call __morus1280_update
607         call __morus1280_update
608
609         /* xor tag: */
610         vmovdqu (%rsi), MSG
611
612         vpxor STATE0, MSG, MSG
613         vpermq $MASK3, STATE1, T0
614         vpxor T0, MSG, MSG
615         vpand STATE2, STATE3, T0
616         vpxor T0, MSG, MSG
617         vmovdqu MSG, (%rsi)
618
619         FRAME_END
620         ret
621 ENDPROC(crypto_morus1280_avx2_final)