Linux-libre 5.4.47-gnu
[librecmc/linux-libre.git] / arch / x86 / crypto / poly1305-sse2-x86_64.S
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Poly1305 authenticator algorithm, RFC7539, x64 SSE2 functions
4  *
5  * Copyright (C) 2015 Martin Willi
6  */
7
8 #include <linux/linkage.h>
9
10 .section        .rodata.cst16.ANMASK, "aM", @progbits, 16
11 .align 16
12 ANMASK: .octa 0x0000000003ffffff0000000003ffffff
13
14 .section        .rodata.cst16.ORMASK, "aM", @progbits, 16
15 .align 16
16 ORMASK: .octa 0x00000000010000000000000001000000
17
18 .text
19
20 #define h0 0x00(%rdi)
21 #define h1 0x04(%rdi)
22 #define h2 0x08(%rdi)
23 #define h3 0x0c(%rdi)
24 #define h4 0x10(%rdi)
25 #define r0 0x00(%rdx)
26 #define r1 0x04(%rdx)
27 #define r2 0x08(%rdx)
28 #define r3 0x0c(%rdx)
29 #define r4 0x10(%rdx)
30 #define s1 0x00(%rsp)
31 #define s2 0x04(%rsp)
32 #define s3 0x08(%rsp)
33 #define s4 0x0c(%rsp)
34 #define m %rsi
35 #define h01 %xmm0
36 #define h23 %xmm1
37 #define h44 %xmm2
38 #define t1 %xmm3
39 #define t2 %xmm4
40 #define t3 %xmm5
41 #define t4 %xmm6
42 #define mask %xmm7
43 #define d0 %r8
44 #define d1 %r9
45 #define d2 %r10
46 #define d3 %r11
47 #define d4 %r12
48
49 ENTRY(poly1305_block_sse2)
50         # %rdi: Accumulator h[5]
51         # %rsi: 16 byte input block m
52         # %rdx: Poly1305 key r[5]
53         # %rcx: Block count
54
55         # This single block variant tries to improve performance by doing two
56         # multiplications in parallel using SSE instructions. There is quite
57         # some quardword packing involved, hence the speedup is marginal.
58
59         push            %rbx
60         push            %r12
61         sub             $0x10,%rsp
62
63         # s1..s4 = r1..r4 * 5
64         mov             r1,%eax
65         lea             (%eax,%eax,4),%eax
66         mov             %eax,s1
67         mov             r2,%eax
68         lea             (%eax,%eax,4),%eax
69         mov             %eax,s2
70         mov             r3,%eax
71         lea             (%eax,%eax,4),%eax
72         mov             %eax,s3
73         mov             r4,%eax
74         lea             (%eax,%eax,4),%eax
75         mov             %eax,s4
76
77         movdqa          ANMASK(%rip),mask
78
79 .Ldoblock:
80         # h01 = [0, h1, 0, h0]
81         # h23 = [0, h3, 0, h2]
82         # h44 = [0, h4, 0, h4]
83         movd            h0,h01
84         movd            h1,t1
85         movd            h2,h23
86         movd            h3,t2
87         movd            h4,h44
88         punpcklqdq      t1,h01
89         punpcklqdq      t2,h23
90         punpcklqdq      h44,h44
91
92         # h01 += [ (m[3-6] >> 2) & 0x3ffffff, m[0-3] & 0x3ffffff ]
93         movd            0x00(m),t1
94         movd            0x03(m),t2
95         psrld           $2,t2
96         punpcklqdq      t2,t1
97         pand            mask,t1
98         paddd           t1,h01
99         # h23 += [ (m[9-12] >> 6) & 0x3ffffff, (m[6-9] >> 4) & 0x3ffffff ]
100         movd            0x06(m),t1
101         movd            0x09(m),t2
102         psrld           $4,t1
103         psrld           $6,t2
104         punpcklqdq      t2,t1
105         pand            mask,t1
106         paddd           t1,h23
107         # h44 += [ (m[12-15] >> 8) | (1 << 24), (m[12-15] >> 8) | (1 << 24) ]
108         mov             0x0c(m),%eax
109         shr             $8,%eax
110         or              $0x01000000,%eax
111         movd            %eax,t1
112         pshufd          $0xc4,t1,t1
113         paddd           t1,h44
114
115         # t1[0] = h0 * r0 + h2 * s3
116         # t1[1] = h1 * s4 + h3 * s2
117         movd            r0,t1
118         movd            s4,t2
119         punpcklqdq      t2,t1
120         pmuludq         h01,t1
121         movd            s3,t2
122         movd            s2,t3
123         punpcklqdq      t3,t2
124         pmuludq         h23,t2
125         paddq           t2,t1
126         # t2[0] = h0 * r1 + h2 * s4
127         # t2[1] = h1 * r0 + h3 * s3
128         movd            r1,t2
129         movd            r0,t3
130         punpcklqdq      t3,t2
131         pmuludq         h01,t2
132         movd            s4,t3
133         movd            s3,t4
134         punpcklqdq      t4,t3
135         pmuludq         h23,t3
136         paddq           t3,t2
137         # t3[0] = h4 * s1
138         # t3[1] = h4 * s2
139         movd            s1,t3
140         movd            s2,t4
141         punpcklqdq      t4,t3
142         pmuludq         h44,t3
143         # d0 = t1[0] + t1[1] + t3[0]
144         # d1 = t2[0] + t2[1] + t3[1]
145         movdqa          t1,t4
146         punpcklqdq      t2,t4
147         punpckhqdq      t2,t1
148         paddq           t4,t1
149         paddq           t3,t1
150         movq            t1,d0
151         psrldq          $8,t1
152         movq            t1,d1
153
154         # t1[0] = h0 * r2 + h2 * r0
155         # t1[1] = h1 * r1 + h3 * s4
156         movd            r2,t1
157         movd            r1,t2
158         punpcklqdq      t2,t1
159         pmuludq         h01,t1
160         movd            r0,t2
161         movd            s4,t3
162         punpcklqdq      t3,t2
163         pmuludq         h23,t2
164         paddq           t2,t1
165         # t2[0] = h0 * r3 + h2 * r1
166         # t2[1] = h1 * r2 + h3 * r0
167         movd            r3,t2
168         movd            r2,t3
169         punpcklqdq      t3,t2
170         pmuludq         h01,t2
171         movd            r1,t3
172         movd            r0,t4
173         punpcklqdq      t4,t3
174         pmuludq         h23,t3
175         paddq           t3,t2
176         # t3[0] = h4 * s3
177         # t3[1] = h4 * s4
178         movd            s3,t3
179         movd            s4,t4
180         punpcklqdq      t4,t3
181         pmuludq         h44,t3
182         # d2 = t1[0] + t1[1] + t3[0]
183         # d3 = t2[0] + t2[1] + t3[1]
184         movdqa          t1,t4
185         punpcklqdq      t2,t4
186         punpckhqdq      t2,t1
187         paddq           t4,t1
188         paddq           t3,t1
189         movq            t1,d2
190         psrldq          $8,t1
191         movq            t1,d3
192
193         # t1[0] = h0 * r4 + h2 * r2
194         # t1[1] = h1 * r3 + h3 * r1
195         movd            r4,t1
196         movd            r3,t2
197         punpcklqdq      t2,t1
198         pmuludq         h01,t1
199         movd            r2,t2
200         movd            r1,t3
201         punpcklqdq      t3,t2
202         pmuludq         h23,t2
203         paddq           t2,t1
204         # t3[0] = h4 * r0
205         movd            r0,t3
206         pmuludq         h44,t3
207         # d4 = t1[0] + t1[1] + t3[0]
208         movdqa          t1,t4
209         psrldq          $8,t4
210         paddq           t4,t1
211         paddq           t3,t1
212         movq            t1,d4
213
214         # d1 += d0 >> 26
215         mov             d0,%rax
216         shr             $26,%rax
217         add             %rax,d1
218         # h0 = d0 & 0x3ffffff
219         mov             d0,%rbx
220         and             $0x3ffffff,%ebx
221
222         # d2 += d1 >> 26
223         mov             d1,%rax
224         shr             $26,%rax
225         add             %rax,d2
226         # h1 = d1 & 0x3ffffff
227         mov             d1,%rax
228         and             $0x3ffffff,%eax
229         mov             %eax,h1
230
231         # d3 += d2 >> 26
232         mov             d2,%rax
233         shr             $26,%rax
234         add             %rax,d3
235         # h2 = d2 & 0x3ffffff
236         mov             d2,%rax
237         and             $0x3ffffff,%eax
238         mov             %eax,h2
239
240         # d4 += d3 >> 26
241         mov             d3,%rax
242         shr             $26,%rax
243         add             %rax,d4
244         # h3 = d3 & 0x3ffffff
245         mov             d3,%rax
246         and             $0x3ffffff,%eax
247         mov             %eax,h3
248
249         # h0 += (d4 >> 26) * 5
250         mov             d4,%rax
251         shr             $26,%rax
252         lea             (%rax,%rax,4),%rax
253         add             %rax,%rbx
254         # h4 = d4 & 0x3ffffff
255         mov             d4,%rax
256         and             $0x3ffffff,%eax
257         mov             %eax,h4
258
259         # h1 += h0 >> 26
260         mov             %rbx,%rax
261         shr             $26,%rax
262         add             %eax,h1
263         # h0 = h0 & 0x3ffffff
264         andl            $0x3ffffff,%ebx
265         mov             %ebx,h0
266
267         add             $0x10,m
268         dec             %rcx
269         jnz             .Ldoblock
270
271         # Zeroing of key material
272         mov             %rcx,0x00(%rsp)
273         mov             %rcx,0x08(%rsp)
274
275         add             $0x10,%rsp
276         pop             %r12
277         pop             %rbx
278         ret
279 ENDPROC(poly1305_block_sse2)
280
281
282 #define u0 0x00(%r8)
283 #define u1 0x04(%r8)
284 #define u2 0x08(%r8)
285 #define u3 0x0c(%r8)
286 #define u4 0x10(%r8)
287 #define hc0 %xmm0
288 #define hc1 %xmm1
289 #define hc2 %xmm2
290 #define hc3 %xmm5
291 #define hc4 %xmm6
292 #define ru0 %xmm7
293 #define ru1 %xmm8
294 #define ru2 %xmm9
295 #define ru3 %xmm10
296 #define ru4 %xmm11
297 #define sv1 %xmm12
298 #define sv2 %xmm13
299 #define sv3 %xmm14
300 #define sv4 %xmm15
301 #undef d0
302 #define d0 %r13
303
304 ENTRY(poly1305_2block_sse2)
305         # %rdi: Accumulator h[5]
306         # %rsi: 16 byte input block m
307         # %rdx: Poly1305 key r[5]
308         # %rcx: Doubleblock count
309         # %r8:  Poly1305 derived key r^2 u[5]
310
311         # This two-block variant further improves performance by using loop
312         # unrolled block processing. This is more straight forward and does
313         # less byte shuffling, but requires a second Poly1305 key r^2:
314         # h = (h + m) * r    =>    h = (h + m1) * r^2 + m2 * r
315
316         push            %rbx
317         push            %r12
318         push            %r13
319
320         # combine r0,u0
321         movd            u0,ru0
322         movd            r0,t1
323         punpcklqdq      t1,ru0
324
325         # combine r1,u1 and s1=r1*5,v1=u1*5
326         movd            u1,ru1
327         movd            r1,t1
328         punpcklqdq      t1,ru1
329         movdqa          ru1,sv1
330         pslld           $2,sv1
331         paddd           ru1,sv1
332
333         # combine r2,u2 and s2=r2*5,v2=u2*5
334         movd            u2,ru2
335         movd            r2,t1
336         punpcklqdq      t1,ru2
337         movdqa          ru2,sv2
338         pslld           $2,sv2
339         paddd           ru2,sv2
340
341         # combine r3,u3 and s3=r3*5,v3=u3*5
342         movd            u3,ru3
343         movd            r3,t1
344         punpcklqdq      t1,ru3
345         movdqa          ru3,sv3
346         pslld           $2,sv3
347         paddd           ru3,sv3
348
349         # combine r4,u4 and s4=r4*5,v4=u4*5
350         movd            u4,ru4
351         movd            r4,t1
352         punpcklqdq      t1,ru4
353         movdqa          ru4,sv4
354         pslld           $2,sv4
355         paddd           ru4,sv4
356
357 .Ldoblock2:
358         # hc0 = [ m[16-19] & 0x3ffffff, h0 + m[0-3] & 0x3ffffff ]
359         movd            0x00(m),hc0
360         movd            0x10(m),t1
361         punpcklqdq      t1,hc0
362         pand            ANMASK(%rip),hc0
363         movd            h0,t1
364         paddd           t1,hc0
365         # hc1 = [ (m[19-22] >> 2) & 0x3ffffff, h1 + (m[3-6] >> 2) & 0x3ffffff ]
366         movd            0x03(m),hc1
367         movd            0x13(m),t1
368         punpcklqdq      t1,hc1
369         psrld           $2,hc1
370         pand            ANMASK(%rip),hc1
371         movd            h1,t1
372         paddd           t1,hc1
373         # hc2 = [ (m[22-25] >> 4) & 0x3ffffff, h2 + (m[6-9] >> 4) & 0x3ffffff ]
374         movd            0x06(m),hc2
375         movd            0x16(m),t1
376         punpcklqdq      t1,hc2
377         psrld           $4,hc2
378         pand            ANMASK(%rip),hc2
379         movd            h2,t1
380         paddd           t1,hc2
381         # hc3 = [ (m[25-28] >> 6) & 0x3ffffff, h3 + (m[9-12] >> 6) & 0x3ffffff ]
382         movd            0x09(m),hc3
383         movd            0x19(m),t1
384         punpcklqdq      t1,hc3
385         psrld           $6,hc3
386         pand            ANMASK(%rip),hc3
387         movd            h3,t1
388         paddd           t1,hc3
389         # hc4 = [ (m[28-31] >> 8) | (1<<24), h4 + (m[12-15] >> 8) | (1<<24) ]
390         movd            0x0c(m),hc4
391         movd            0x1c(m),t1
392         punpcklqdq      t1,hc4
393         psrld           $8,hc4
394         por             ORMASK(%rip),hc4
395         movd            h4,t1
396         paddd           t1,hc4
397
398         # t1 = [ hc0[1] * r0, hc0[0] * u0 ]
399         movdqa          ru0,t1
400         pmuludq         hc0,t1
401         # t1 += [ hc1[1] * s4, hc1[0] * v4 ]
402         movdqa          sv4,t2
403         pmuludq         hc1,t2
404         paddq           t2,t1
405         # t1 += [ hc2[1] * s3, hc2[0] * v3 ]
406         movdqa          sv3,t2
407         pmuludq         hc2,t2
408         paddq           t2,t1
409         # t1 += [ hc3[1] * s2, hc3[0] * v2 ]
410         movdqa          sv2,t2
411         pmuludq         hc3,t2
412         paddq           t2,t1
413         # t1 += [ hc4[1] * s1, hc4[0] * v1 ]
414         movdqa          sv1,t2
415         pmuludq         hc4,t2
416         paddq           t2,t1
417         # d0 = t1[0] + t1[1]
418         movdqa          t1,t2
419         psrldq          $8,t2
420         paddq           t2,t1
421         movq            t1,d0
422
423         # t1 = [ hc0[1] * r1, hc0[0] * u1 ]
424         movdqa          ru1,t1
425         pmuludq         hc0,t1
426         # t1 += [ hc1[1] * r0, hc1[0] * u0 ]
427         movdqa          ru0,t2
428         pmuludq         hc1,t2
429         paddq           t2,t1
430         # t1 += [ hc2[1] * s4, hc2[0] * v4 ]
431         movdqa          sv4,t2
432         pmuludq         hc2,t2
433         paddq           t2,t1
434         # t1 += [ hc3[1] * s3, hc3[0] * v3 ]
435         movdqa          sv3,t2
436         pmuludq         hc3,t2
437         paddq           t2,t1
438         # t1 += [ hc4[1] * s2, hc4[0] * v2 ]
439         movdqa          sv2,t2
440         pmuludq         hc4,t2
441         paddq           t2,t1
442         # d1 = t1[0] + t1[1]
443         movdqa          t1,t2
444         psrldq          $8,t2
445         paddq           t2,t1
446         movq            t1,d1
447
448         # t1 = [ hc0[1] * r2, hc0[0] * u2 ]
449         movdqa          ru2,t1
450         pmuludq         hc0,t1
451         # t1 += [ hc1[1] * r1, hc1[0] * u1 ]
452         movdqa          ru1,t2
453         pmuludq         hc1,t2
454         paddq           t2,t1
455         # t1 += [ hc2[1] * r0, hc2[0] * u0 ]
456         movdqa          ru0,t2
457         pmuludq         hc2,t2
458         paddq           t2,t1
459         # t1 += [ hc3[1] * s4, hc3[0] * v4 ]
460         movdqa          sv4,t2
461         pmuludq         hc3,t2
462         paddq           t2,t1
463         # t1 += [ hc4[1] * s3, hc4[0] * v3 ]
464         movdqa          sv3,t2
465         pmuludq         hc4,t2
466         paddq           t2,t1
467         # d2 = t1[0] + t1[1]
468         movdqa          t1,t2
469         psrldq          $8,t2
470         paddq           t2,t1
471         movq            t1,d2
472
473         # t1 = [ hc0[1] * r3, hc0[0] * u3 ]
474         movdqa          ru3,t1
475         pmuludq         hc0,t1
476         # t1 += [ hc1[1] * r2, hc1[0] * u2 ]
477         movdqa          ru2,t2
478         pmuludq         hc1,t2
479         paddq           t2,t1
480         # t1 += [ hc2[1] * r1, hc2[0] * u1 ]
481         movdqa          ru1,t2
482         pmuludq         hc2,t2
483         paddq           t2,t1
484         # t1 += [ hc3[1] * r0, hc3[0] * u0 ]
485         movdqa          ru0,t2
486         pmuludq         hc3,t2
487         paddq           t2,t1
488         # t1 += [ hc4[1] * s4, hc4[0] * v4 ]
489         movdqa          sv4,t2
490         pmuludq         hc4,t2
491         paddq           t2,t1
492         # d3 = t1[0] + t1[1]
493         movdqa          t1,t2
494         psrldq          $8,t2
495         paddq           t2,t1
496         movq            t1,d3
497
498         # t1 = [ hc0[1] * r4, hc0[0] * u4 ]
499         movdqa          ru4,t1
500         pmuludq         hc0,t1
501         # t1 += [ hc1[1] * r3, hc1[0] * u3 ]
502         movdqa          ru3,t2
503         pmuludq         hc1,t2
504         paddq           t2,t1
505         # t1 += [ hc2[1] * r2, hc2[0] * u2 ]
506         movdqa          ru2,t2
507         pmuludq         hc2,t2
508         paddq           t2,t1
509         # t1 += [ hc3[1] * r1, hc3[0] * u1 ]
510         movdqa          ru1,t2
511         pmuludq         hc3,t2
512         paddq           t2,t1
513         # t1 += [ hc4[1] * r0, hc4[0] * u0 ]
514         movdqa          ru0,t2
515         pmuludq         hc4,t2
516         paddq           t2,t1
517         # d4 = t1[0] + t1[1]
518         movdqa          t1,t2
519         psrldq          $8,t2
520         paddq           t2,t1
521         movq            t1,d4
522
523         # Now do a partial reduction mod (2^130)-5, carrying h0 -> h1 -> h2 ->
524         # h3 -> h4 -> h0 -> h1 to get h0,h2,h3,h4 < 2^26 and h1 < 2^26 + a small
525         # amount.  Careful: we must not assume the carry bits 'd0 >> 26',
526         # 'd1 >> 26', 'd2 >> 26', 'd3 >> 26', and '(d4 >> 26) * 5' fit in 32-bit
527         # integers.  It's true in a single-block implementation, but not here.
528
529         # d1 += d0 >> 26
530         mov             d0,%rax
531         shr             $26,%rax
532         add             %rax,d1
533         # h0 = d0 & 0x3ffffff
534         mov             d0,%rbx
535         and             $0x3ffffff,%ebx
536
537         # d2 += d1 >> 26
538         mov             d1,%rax
539         shr             $26,%rax
540         add             %rax,d2
541         # h1 = d1 & 0x3ffffff
542         mov             d1,%rax
543         and             $0x3ffffff,%eax
544         mov             %eax,h1
545
546         # d3 += d2 >> 26
547         mov             d2,%rax
548         shr             $26,%rax
549         add             %rax,d3
550         # h2 = d2 & 0x3ffffff
551         mov             d2,%rax
552         and             $0x3ffffff,%eax
553         mov             %eax,h2
554
555         # d4 += d3 >> 26
556         mov             d3,%rax
557         shr             $26,%rax
558         add             %rax,d4
559         # h3 = d3 & 0x3ffffff
560         mov             d3,%rax
561         and             $0x3ffffff,%eax
562         mov             %eax,h3
563
564         # h0 += (d4 >> 26) * 5
565         mov             d4,%rax
566         shr             $26,%rax
567         lea             (%rax,%rax,4),%rax
568         add             %rax,%rbx
569         # h4 = d4 & 0x3ffffff
570         mov             d4,%rax
571         and             $0x3ffffff,%eax
572         mov             %eax,h4
573
574         # h1 += h0 >> 26
575         mov             %rbx,%rax
576         shr             $26,%rax
577         add             %eax,h1
578         # h0 = h0 & 0x3ffffff
579         andl            $0x3ffffff,%ebx
580         mov             %ebx,h0
581
582         add             $0x20,m
583         dec             %rcx
584         jnz             .Ldoblock2
585
586         pop             %r13
587         pop             %r12
588         pop             %rbx
589         ret
590 ENDPROC(poly1305_2block_sse2)