Enable AMD64 SHA512 implementations for WIN64
[libgcrypt.git] / cipher / rijndael-amd64.S
1 /* rinjdael-amd64.S  -  AMD64 assembly implementation of AES cipher
2  *
3  * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
4  *
5  * This file is part of Libgcrypt.
6  *
7  * Libgcrypt is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * Libgcrypt is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #ifdef __x86_64
22 #include <config.h>
23 #if defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && defined(USE_AES)
24
25 #ifdef __PIC__
26 #  define RIP (%rip)
27 #else
28 #  define RIP
29 #endif
30
31 .text
32
33 /* table macros */
34 #define E0      (0)
35 #define Es0     (1)
36 #define Esize   4
37 #define Essize  4
38
39 #define D0      (0)
40 #define Ds0     (4 * 256)
41 #define Dsize   4
42 #define Dssize  1
43
44 /* register macros */
45 #define CTX     %rdi
46 #define RTAB    %r12
47
48 #define RA      %rax
49 #define RB      %rbx
50 #define RC      %rcx
51 #define RD      %rdx
52
53 #define RAd     %eax
54 #define RBd     %ebx
55 #define RCd     %ecx
56 #define RDd     %edx
57
58 #define RAbl    %al
59 #define RBbl    %bl
60 #define RCbl    %cl
61 #define RDbl    %dl
62
63 #define RAbh    %ah
64 #define RBbh    %bh
65 #define RCbh    %ch
66 #define RDbh    %dh
67
68 #define RNA     %r8
69 #define RNB     %r9
70 #define RNC     %r10
71 #define RND     %r11
72
73 #define RNAd    %r8d
74 #define RNBd    %r9d
75 #define RNCd    %r10d
76 #define RNDd    %r11d
77
78 #define RT0     %rbp
79 #define RT1     %rsi
80
81 #define RT0d    %ebp
82 #define RT1d    %esi
83
84 /* helper macros */
85 #define do16bit(op, source, tablemul, table1, dest1, table2, dest2, t0, t1) \
86         movzbl source ## bl,                    t0 ## d; \
87         movzbl source ## bh,                    t1 ## d; \
88         op ## l table1(RTAB,t0,tablemul),       dest1 ## d; \
89         op ## l table2(RTAB,t1,tablemul),       dest2 ## d;
90
91 #define do16bit_shr(shf, op, source, tablemul, table1, dest1, table2, dest2, t0, t1) \
92         movzbl source ## bl,                    t0 ## d; \
93         movzbl source ## bh,                    t1 ## d; \
94         shrl $(shf),                            source ## d; \
95         op ## l table1(RTAB,t0,tablemul),       dest1 ## d; \
96         op ## l table2(RTAB,t1,tablemul),       dest2 ## d;
97
98 #define last_do16bit(op, source, tablemul, table1, dest1, table2, dest2, t0, t1) \
99         movzbl source ## bl,                    t0 ## d; \
100         movzbl source ## bh,                    t1 ## d; \
101         movzbl table1(RTAB,t0,tablemul),        t0 ## d; \
102         movzbl table2(RTAB,t1,tablemul),        t1 ## d; \
103         op ## l t0 ## d,                        dest1 ## d; \
104         op ## l t1 ## d,                        dest2 ## d;
105
106 #define last_do16bit_shr(shf, op, source, tablemul, table1, dest1, table2, dest2, t0, t1) \
107         movzbl source ## bl,                    t0 ## d; \
108         movzbl source ## bh,                    t1 ## d; \
109         shrl $(shf),                            source ## d; \
110         movzbl table1(RTAB,t0,tablemul),        t0 ## d; \
111         movzbl table2(RTAB,t1,tablemul),        t1 ## d; \
112         op ## l t0 ## d,                        dest1 ## d; \
113         op ## l t1 ## d,                        dest2 ## d;
114
115 /***********************************************************************
116  * AMD64 assembly implementation of the AES cipher
117  ***********************************************************************/
118 #define addroundkey(round, ra, rb, rc, rd) \
119         xorl (((round) * 16) + 0 * 4)(CTX), ra ## d; \
120         xorl (((round) * 16) + 1 * 4)(CTX), rb ## d; \
121         xorl (((round) * 16) + 2 * 4)(CTX), rc ## d; \
122         xorl (((round) * 16) + 3 * 4)(CTX), rd ## d;
123
124 #define do_encround(next_r) \
125         do16bit_shr(16, mov, RA, Esize, E0, RNA, E0, RND, RT0, RT1); \
126         do16bit(        mov, RA, Esize, E0, RNC, E0, RNB, RT0, RT1); \
127         movl (((next_r) * 16) + 0 * 4)(CTX), RAd; \
128         roll $8, RNDd; \
129         xorl RNAd, RAd; \
130         roll $8, RNCd; \
131         roll $8, RNBd; \
132         roll $8, RAd; \
133         \
134         do16bit_shr(16, xor, RD, Esize, E0, RND, E0, RNC, RT0, RT1); \
135         do16bit(        xor, RD, Esize, E0, RNB, E0, RA,  RT0, RT1); \
136         movl (((next_r) * 16) + 3 * 4)(CTX), RDd; \
137         roll $8, RNCd; \
138         xorl RNDd, RDd; \
139         roll $8, RNBd; \
140         roll $8, RAd; \
141         roll $8, RDd; \
142         \
143         do16bit_shr(16, xor, RC, Esize, E0, RNC, E0, RNB, RT0, RT1); \
144         do16bit(        xor, RC, Esize, E0, RA,  E0, RD,  RT0, RT1); \
145         movl (((next_r) * 16) + 2 * 4)(CTX), RCd; \
146         roll $8, RNBd; \
147         xorl RNCd, RCd; \
148         roll $8, RAd; \
149         roll $8, RDd; \
150         roll $8, RCd; \
151         \
152         do16bit_shr(16, xor, RB, Esize, E0, RNB, E0, RA,  RT0, RT1); \
153         do16bit(        xor, RB, Esize, E0, RD,  E0, RC,  RT0, RT1); \
154         movl (((next_r) * 16) + 1 * 4)(CTX), RBd; \
155         roll $8, RAd; \
156         xorl RNBd, RBd; \
157         roll $16, RDd; \
158         roll $24, RCd;
159
160 #define do_lastencround(next_r) \
161         do16bit_shr(16, movzb, RA, Essize, Es0, RNA, Es0, RND, RT0, RT1); \
162         do16bit(        movzb, RA, Essize, Es0, RNC, Es0, RNB, RT0, RT1); \
163         movl (((next_r) * 16) + 0 * 4)(CTX), RAd; \
164         roll $8, RNDd; \
165         xorl RNAd, RAd; \
166         roll $8, RNCd; \
167         roll $8, RNBd; \
168         roll $8, RAd; \
169         \
170         last_do16bit_shr(16, xor, RD, Essize, Es0, RND, Es0, RNC, RT0, RT1); \
171         last_do16bit(        xor, RD, Essize, Es0, RNB, Es0, RA,  RT0, RT1); \
172         movl (((next_r) * 16) + 3 * 4)(CTX), RDd; \
173         roll $8, RNCd; \
174         xorl RNDd, RDd; \
175         roll $8, RNBd; \
176         roll $8, RAd; \
177         roll $8, RDd; \
178         \
179         last_do16bit_shr(16, xor, RC, Essize, Es0, RNC, Es0, RNB, RT0, RT1); \
180         last_do16bit(        xor, RC, Essize, Es0, RA,  Es0, RD,  RT0, RT1); \
181         movl (((next_r) * 16) + 2 * 4)(CTX), RCd; \
182         roll $8, RNBd; \
183         xorl RNCd, RCd; \
184         roll $8, RAd; \
185         roll $8, RDd; \
186         roll $8, RCd; \
187         \
188         last_do16bit_shr(16, xor, RB, Essize, Es0, RNB, Es0, RA,  RT0, RT1); \
189         last_do16bit(        xor, RB, Essize, Es0, RD,  Es0, RC,  RT0, RT1); \
190         movl (((next_r) * 16) + 1 * 4)(CTX), RBd; \
191         roll $8, RAd; \
192         xorl RNBd, RBd; \
193         roll $16, RDd; \
194         roll $24, RCd;
195
196 #define firstencround(round) \
197         addroundkey(round, RA, RB, RC, RD); \
198         do_encround((round) + 1);
199
200 #define encround(round) \
201         do_encround((round) + 1);
202
203 #define lastencround(round) \
204         do_lastencround((round) + 1);
205
206 .align 8
207 .globl _gcry_aes_amd64_encrypt_block
208 .type   _gcry_aes_amd64_encrypt_block,@function;
209
210 _gcry_aes_amd64_encrypt_block:
211         /* input:
212          *      %rdi: keysched, CTX
213          *      %rsi: dst
214          *      %rdx: src
215          *      %ecx: number of rounds.. 10, 12 or 14
216          *      %r8:  encryption tables
217          */
218         subq $(5 * 8), %rsp;
219         movq %rsi, (0 * 8)(%rsp);
220         movl %ecx, (1 * 8)(%rsp);
221         movq %rbp, (2 * 8)(%rsp);
222         movq %rbx, (3 * 8)(%rsp);
223         movq %r12, (4 * 8)(%rsp);
224
225         leaq (%r8), RTAB;
226
227         /* read input block */
228         movl 0 * 4(%rdx), RAd;
229         movl 1 * 4(%rdx), RBd;
230         movl 2 * 4(%rdx), RCd;
231         movl 3 * 4(%rdx), RDd;
232
233         firstencround(0);
234         encround(1);
235         encround(2);
236         encround(3);
237         encround(4);
238         encround(5);
239         encround(6);
240         encround(7);
241         encround(8);
242         cmpl $12, (1 * 8)(%rsp);
243         jnb .Lenc_not_128;
244         lastencround(9);
245
246 .align 4
247 .Lenc_done:
248         /* write output block */
249         movq (0 * 8)(%rsp), %rsi;
250         movl RAd, 0 * 4(%rsi);
251         movl RBd, 1 * 4(%rsi);
252         movl RCd, 2 * 4(%rsi);
253         movl RDd, 3 * 4(%rsi);
254
255         movq (4 * 8)(%rsp), %r12;
256         movq (3 * 8)(%rsp), %rbx;
257         movq (2 * 8)(%rsp), %rbp;
258         addq $(5 * 8), %rsp;
259
260         movl $(6 * 8), %eax;
261         ret;
262
263 .align 4
264 .Lenc_not_128:
265         je .Lenc_192
266
267         encround(9);
268         encround(10);
269         encround(11);
270         encround(12);
271         lastencround(13);
272
273         jmp .Lenc_done;
274
275 .align 4
276 .Lenc_192:
277         encround(9);
278         encround(10);
279         lastencround(11);
280
281         jmp .Lenc_done;
282 .size _gcry_aes_amd64_encrypt_block,.-_gcry_aes_amd64_encrypt_block;
283
284 #define do_decround(next_r) \
285         do16bit_shr(16, mov, RA, Dsize, D0, RNA, D0, RNB, RT0, RT1); \
286         do16bit(        mov, RA, Dsize, D0, RNC, D0, RND, RT0, RT1); \
287         movl (((next_r) * 16) + 0 * 4)(CTX), RAd; \
288         roll $8, RNBd; \
289         xorl RNAd, RAd; \
290         roll $8, RNCd; \
291         roll $8, RNDd; \
292         roll $8, RAd; \
293         \
294         do16bit_shr(16, xor, RB, Dsize, D0, RNB, D0, RNC, RT0, RT1); \
295         do16bit(        xor, RB, Dsize, D0, RND, D0, RA,  RT0, RT1); \
296         movl (((next_r) * 16) + 1 * 4)(CTX), RBd; \
297         roll $8, RNCd; \
298         xorl RNBd, RBd; \
299         roll $8, RNDd; \
300         roll $8, RAd; \
301         roll $8, RBd; \
302         \
303         do16bit_shr(16, xor, RC, Dsize, D0, RNC, D0, RND, RT0, RT1); \
304         do16bit(        xor, RC, Dsize, D0, RA,  D0, RB,  RT0, RT1); \
305         movl (((next_r) * 16) + 2 * 4)(CTX), RCd; \
306         roll $8, RNDd; \
307         xorl RNCd, RCd; \
308         roll $8, RAd; \
309         roll $8, RBd; \
310         roll $8, RCd; \
311         \
312         do16bit_shr(16, xor, RD, Dsize, D0, RND, D0, RA,  RT0, RT1); \
313         do16bit(        xor, RD, Dsize, D0, RB,  D0, RC,  RT0, RT1); \
314         movl (((next_r) * 16) + 3 * 4)(CTX), RDd; \
315         roll $8, RAd; \
316         xorl RNDd, RDd; \
317         roll $16, RBd; \
318         roll $24, RCd;
319
320 #define do_lastdecround(next_r) \
321         do16bit_shr(16, movzb, RA, Dssize, Ds0, RNA, Ds0, RNB, RT0, RT1); \
322         do16bit(        movzb, RA, Dssize, Ds0, RNC, Ds0, RND, RT0, RT1); \
323         movl (((next_r) * 16) + 0 * 4)(CTX), RAd; \
324         roll $8, RNBd; \
325         xorl RNAd, RAd; \
326         roll $8, RNCd; \
327         roll $8, RNDd; \
328         roll $8, RAd; \
329         \
330         last_do16bit_shr(16, xor, RB, Dssize, Ds0, RNB, Ds0, RNC, RT0, RT1); \
331         last_do16bit(        xor, RB, Dssize, Ds0, RND, Ds0, RA,  RT0, RT1); \
332         movl (((next_r) * 16) + 1 * 4)(CTX), RBd; \
333         roll $8, RNCd; \
334         xorl RNBd, RBd; \
335         roll $8, RNDd; \
336         roll $8, RAd; \
337         roll $8, RBd; \
338         \
339         last_do16bit_shr(16, xor, RC, Dssize, Ds0, RNC, Ds0, RND, RT0, RT1); \
340         last_do16bit(        xor, RC, Dssize, Ds0, RA,  Ds0, RB,  RT0, RT1); \
341         movl (((next_r) * 16) + 2 * 4)(CTX), RCd; \
342         roll $8, RNDd; \
343         xorl RNCd, RCd; \
344         roll $8, RAd; \
345         roll $8, RBd; \
346         roll $8, RCd; \
347         \
348         last_do16bit_shr(16, xor, RD, Dssize, Ds0, RND, Ds0, RA,  RT0, RT1); \
349         last_do16bit(        xor, RD, Dssize, Ds0, RB,  Ds0, RC,  RT0, RT1); \
350         movl (((next_r) * 16) + 3 * 4)(CTX), RDd; \
351         roll $8, RAd; \
352         xorl RNDd, RDd; \
353         roll $16, RBd; \
354         roll $24, RCd;
355
356 #define firstdecround(round) \
357         addroundkey((round + 1), RA, RB, RC, RD); \
358         do_decround(round);
359
360 #define decround(round) \
361         do_decround(round);
362
363 #define lastdecround(round) \
364         do_lastdecround(round);
365
366 .align 8
367 .globl _gcry_aes_amd64_decrypt_block
368 .type   _gcry_aes_amd64_decrypt_block,@function;
369
370 _gcry_aes_amd64_decrypt_block:
371         /* input:
372          *      %rdi: keysched, CTX
373          *      %rsi: dst
374          *      %rdx: src
375          *      %ecx: number of rounds.. 10, 12 or 14
376          *      %r8:  decryption tables
377          */
378         subq $(5 * 8), %rsp;
379         movq %rsi, (0 * 8)(%rsp);
380         movl %ecx, (1 * 8)(%rsp);
381         movq %rbp, (2 * 8)(%rsp);
382         movq %rbx, (3 * 8)(%rsp);
383         movq %r12, (4 * 8)(%rsp);
384
385         leaq (%r8), RTAB;
386
387         /* read input block */
388         movl 0 * 4(%rdx), RAd;
389         movl 1 * 4(%rdx), RBd;
390         movl 2 * 4(%rdx), RCd;
391         movl 3 * 4(%rdx), RDd;
392
393         cmpl $12, (1 * 8)(%rsp);
394         jnb .Ldec_256;
395
396         firstdecround(9);
397 .align 4
398 .Ldec_tail:
399         decround(8);
400         decround(7);
401         decround(6);
402         decround(5);
403         decround(4);
404         decround(3);
405         decround(2);
406         decround(1);
407         lastdecround(0);
408
409         /* write output block */
410         movq (0 * 8)(%rsp), %rsi;
411         movl RAd, 0 * 4(%rsi);
412         movl RBd, 1 * 4(%rsi);
413         movl RCd, 2 * 4(%rsi);
414         movl RDd, 3 * 4(%rsi);
415
416         movq (4 * 8)(%rsp), %r12;
417         movq (3 * 8)(%rsp), %rbx;
418         movq (2 * 8)(%rsp), %rbp;
419         addq $(5 * 8), %rsp;
420
421         movl $(6 * 8), %eax;
422         ret;
423
424 .align 4
425 .Ldec_256:
426         je .Ldec_192;
427
428         firstdecround(13);
429         decround(12);
430         decround(11);
431         decround(10);
432         decround(9);
433
434         jmp .Ldec_tail;
435
436 .align 4
437 .Ldec_192:
438         firstdecround(11);
439         decround(10);
440         decround(9);
441
442         jmp .Ldec_tail;
443 .size _gcry_aes_amd64_decrypt_block,.-_gcry_aes_amd64_decrypt_block;
444
445 #endif /*USE_AES*/
446 #endif /*__x86_64*/