pubkey: Re-map all depreccated RSA algo numbers.
[libgcrypt.git] / cipher / serpent-armv7-neon.S
1 /* serpent-armv7-neon.S  -  ARM/NEON assembly implementation of Serpent 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 #include <config.h>
22
23 #if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) && \
24     defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
25     defined(HAVE_GCC_INLINE_ASM_NEON)
26
27 .text
28
29 .syntax unified
30 .fpu neon
31 .arm
32
33 /* ARM registers */
34 #define RROUND r0
35
36 /* NEON vector registers */
37 #define RA0 q0
38 #define RA1 q1
39 #define RA2 q2
40 #define RA3 q3
41 #define RA4 q4
42 #define RB0 q5
43 #define RB1 q6
44 #define RB2 q7
45 #define RB3 q8
46 #define RB4 q9
47
48 #define RT0 q10
49 #define RT1 q11
50 #define RT2 q12
51 #define RT3 q13
52
53 #define RA0d0 d0
54 #define RA0d1 d1
55 #define RA1d0 d2
56 #define RA1d1 d3
57 #define RA2d0 d4
58 #define RA2d1 d5
59 #define RA3d0 d6
60 #define RA3d1 d7
61 #define RA4d0 d8
62 #define RA4d1 d9
63 #define RB0d0 d10
64 #define RB0d1 d11
65 #define RB1d0 d12
66 #define RB1d1 d13
67 #define RB2d0 d14
68 #define RB2d1 d15
69 #define RB3d0 d16
70 #define RB3d1 d17
71 #define RB4d0 d18
72 #define RB4d1 d19
73 #define RT0d0 d20
74 #define RT0d1 d21
75 #define RT1d0 d22
76 #define RT1d1 d23
77 #define RT2d0 d24
78 #define RT2d1 d25
79
80 /**********************************************************************
81   helper macros
82  **********************************************************************/
83
84 #define transpose_4x4(_q0, _q1, _q2, _q3) \
85         vtrn.32 _q0, _q1;       \
86         vtrn.32 _q2, _q3;       \
87         vswp _q0##d1, _q2##d0;  \
88         vswp _q1##d1, _q3##d0;
89
90 /**********************************************************************
91   8-way serpent
92  **********************************************************************/
93
94 /*
95  * These are the S-Boxes of Serpent from following research paper.
96  *
97  *  D. A. Osvik, “Speeding up Serpent,” in Third AES Candidate Conference,
98  *   (New York, New York, USA), p. 317–329, National Institute of Standards and
99  *   Technology, 2000.
100  *
101  * Paper is also available at: http://www.ii.uib.no/~osvik/pub/aes3.pdf
102  *
103  */
104 #define SBOX0(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
105         veor    a3, a3, a0;     veor    b3, b3, b0;     vmov    a4, a1;         vmov    b4, b1;         \
106         vand    a1, a1, a3;     vand    b1, b1, b3;     veor    a4, a4, a2;     veor    b4, b4, b2;     \
107         veor    a1, a1, a0;     veor    b1, b1, b0;     vorr    a0, a0, a3;     vorr    b0, b0, b3;     \
108         veor    a0, a0, a4;     veor    b0, b0, b4;     veor    a4, a4, a3;     veor    b4, b4, b3;     \
109         veor    a3, a3, a2;     veor    b3, b3, b2;     vorr    a2, a2, a1;     vorr    b2, b2, b1;     \
110         veor    a2, a2, a4;     veor    b2, b2, b4;     vmvn    a4, a4;         vmvn    b4, b4;         \
111         vorr    a4, a4, a1;     vorr    b4, b4, b1;     veor    a1, a1, a3;     veor    b1, b1, b3;     \
112         veor    a1, a1, a4;     veor    b1, b1, b4;     vorr    a3, a3, a0;     vorr    b3, b3, b0;     \
113         veor    a1, a1, a3;     veor    b1, b1, b3;     veor    a4, a3;         veor    b4, b3;
114
115 #define SBOX0_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
116         vmvn    a2, a2;         vmvn    b2, b2;         vmov    a4, a1;         vmov    b4, b1;         \
117         vorr    a1, a1, a0;     vorr    b1, b1, b0;     vmvn    a4, a4;         vmvn    b4, b4;         \
118         veor    a1, a1, a2;     veor    b1, b1, b2;     vorr    a2, a2, a4;     vorr    b2, b2, b4;     \
119         veor    a1, a1, a3;     veor    b1, b1, b3;     veor    a0, a0, a4;     veor    b0, b0, b4;     \
120         veor    a2, a2, a0;     veor    b2, b2, b0;     vand    a0, a0, a3;     vand    b0, b0, b3;     \
121         veor    a4, a4, a0;     veor    b4, b4, b0;     vorr    a0, a0, a1;     vorr    b0, b0, b1;     \
122         veor    a0, a0, a2;     veor    b0, b0, b2;     veor    a3, a3, a4;     veor    b3, b3, b4;     \
123         veor    a2, a2, a1;     veor    b2, b2, b1;     veor    a3, a3, a0;     veor    b3, b3, b0;     \
124         veor    a3, a3, a1;     veor    b3, b3, b1;\
125         vand    a2, a2, a3;     vand    b2, b2, b3;\
126         veor    a4, a2; veor    b4, b2;
127
128 #define SBOX1(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
129         vmvn    a0, a0;         vmvn    b0, b0;         vmvn    a2, a2;         vmvn    b2, b2;         \
130         vmov    a4, a0;         vmov    b4, b0;         vand    a0, a0, a1;     vand    b0, b0, b1;     \
131         veor    a2, a2, a0;     veor    b2, b2, b0;     vorr    a0, a0, a3;     vorr    b0, b0, b3;     \
132         veor    a3, a3, a2;     veor    b3, b3, b2;     veor    a1, a1, a0;     veor    b1, b1, b0;     \
133         veor    a0, a0, a4;     veor    b0, b0, b4;     vorr    a4, a4, a1;     vorr    b4, b4, b1;     \
134         veor    a1, a1, a3;     veor    b1, b1, b3;     vorr    a2, a2, a0;     vorr    b2, b2, b0;     \
135         vand    a2, a2, a4;     vand    b2, b2, b4;     veor    a0, a0, a1;     veor    b0, b0, b1;     \
136         vand    a1, a1, a2;     vand    b1, b1, b2;\
137         veor    a1, a1, a0;     veor    b1, b1, b0;     vand    a0, a0, a2;     vand    b0, b0, b2;     \
138         veor    a0, a4;         veor    b0, b4;
139
140 #define SBOX1_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
141         vmov    a4, a1;         vmov    b4, b1;         veor    a1, a1, a3;     veor    b1, b1, b3;     \
142         vand    a3, a3, a1;     vand    b3, b3, b1;     veor    a4, a4, a2;     veor    b4, b4, b2;     \
143         veor    a3, a3, a0;     veor    b3, b3, b0;     vorr    a0, a0, a1;     vorr    b0, b0, b1;     \
144         veor    a2, a2, a3;     veor    b2, b2, b3;     veor    a0, a0, a4;     veor    b0, b0, b4;     \
145         vorr    a0, a0, a2;     vorr    b0, b0, b2;     veor    a1, a1, a3;     veor    b1, b1, b3;     \
146         veor    a0, a0, a1;     veor    b0, b0, b1;     vorr    a1, a1, a3;     vorr    b1, b1, b3;     \
147         veor    a1, a1, a0;     veor    b1, b1, b0;     vmvn    a4, a4;         vmvn    b4, b4;         \
148         veor    a4, a4, a1;     veor    b4, b4, b1;     vorr    a1, a1, a0;     vorr    b1, b1, b0;     \
149         veor    a1, a1, a0;     veor    b1, b1, b0;\
150         vorr    a1, a1, a4;     vorr    b1, b1, b4;\
151         veor    a3, a1;         veor    b3, b1;
152
153 #define SBOX2(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
154         vmov    a4, a0;         vmov    b4, b0;         vand    a0, a0, a2;     vand    b0, b0, b2;     \
155         veor    a0, a0, a3;     veor    b0, b0, b3;     veor    a2, a2, a1;     veor    b2, b2, b1;     \
156         veor    a2, a2, a0;     veor    b2, b2, b0;     vorr    a3, a3, a4;     vorr    b3, b3, b4;     \
157         veor    a3, a3, a1;     veor    b3, b3, b1;     veor    a4, a4, a2;     veor    b4, b4, b2;     \
158         vmov    a1, a3;         vmov    b1, b3;         vorr    a3, a3, a4;     vorr    b3, b3, b4;     \
159         veor    a3, a3, a0;     veor    b3, b3, b0;     vand    a0, a0, a1;     vand    b0, b0, b1;     \
160         veor    a4, a4, a0;     veor    b4, b4, b0;     veor    a1, a1, a3;     veor    b1, b1, b3;     \
161         veor    a1, a1, a4;     veor    b1, b1, b4;     vmvn    a4, a4;         vmvn    b4, b4;
162
163 #define SBOX2_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
164         veor    a2, a2, a3;     veor    b2, b2, b3;     veor    a3, a3, a0;     veor    b3, b3, b0;     \
165         vmov    a4, a3;         vmov    b4, b3;         vand    a3, a3, a2;     vand    b3, b3, b2;     \
166         veor    a3, a3, a1;     veor    b3, b3, b1;     vorr    a1, a1, a2;     vorr    b1, b1, b2;     \
167         veor    a1, a1, a4;     veor    b1, b1, b4;     vand    a4, a4, a3;     vand    b4, b4, b3;     \
168         veor    a2, a2, a3;     veor    b2, b2, b3;     vand    a4, a4, a0;     vand    b4, b4, b0;     \
169         veor    a4, a4, a2;     veor    b4, b4, b2;     vand    a2, a2, a1;     vand    b2, b2, b1;     \
170         vorr    a2, a2, a0;     vorr    b2, b2, b0;     vmvn    a3, a3;         vmvn    b3, b3;         \
171         veor    a2, a2, a3;     veor    b2, b2, b3;     veor    a0, a0, a3;     veor    b0, b0, b3;     \
172         vand    a0, a0, a1;     vand    b0, b0, b1;     veor    a3, a3, a4;     veor    b3, b3, b4;     \
173         veor    a3, a0;         veor    b3, b0;
174
175 #define SBOX3(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
176         vmov    a4, a0;         vmov    b4, b0;         vorr    a0, a0, a3;     vorr    b0, b0, b3;     \
177         veor    a3, a3, a1;     veor    b3, b3, b1;     vand    a1, a1, a4;     vand    b1, b1, b4;     \
178         veor    a4, a4, a2;     veor    b4, b4, b2;     veor    a2, a2, a3;     veor    b2, b2, b3;     \
179         vand    a3, a3, a0;     vand    b3, b3, b0;     vorr    a4, a4, a1;     vorr    b4, b4, b1;     \
180         veor    a3, a3, a4;     veor    b3, b3, b4;     veor    a0, a0, a1;     veor    b0, b0, b1;     \
181         vand    a4, a4, a0;     vand    b4, b4, b0;     veor    a1, a1, a3;     veor    b1, b1, b3;     \
182         veor    a4, a4, a2;     veor    b4, b4, b2;     vorr    a1, a1, a0;     vorr    b1, b1, b0;     \
183         veor    a1, a1, a2;     veor    b1, b1, b2;     veor    a0, a0, a3;     veor    b0, b0, b3;     \
184         vmov    a2, a1;         vmov    b2, b1;         vorr    a1, a1, a3;     vorr    b1, b1, b3;     \
185         veor    a1, a0;         veor    b1, b0;
186
187 #define SBOX3_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
188         vmov    a4, a2;         vmov    b4, b2;         veor    a2, a2, a1;     veor    b2, b2, b1;     \
189         veor    a0, a0, a2;     veor    b0, b0, b2;     vand    a4, a4, a2;     vand    b4, b4, b2;     \
190         veor    a4, a4, a0;     veor    b4, b4, b0;     vand    a0, a0, a1;     vand    b0, b0, b1;     \
191         veor    a1, a1, a3;     veor    b1, b1, b3;     vorr    a3, a3, a4;     vorr    b3, b3, b4;     \
192         veor    a2, a2, a3;     veor    b2, b2, b3;     veor    a0, a0, a3;     veor    b0, b0, b3;     \
193         veor    a1, a1, a4;     veor    b1, b1, b4;     vand    a3, a3, a2;     vand    b3, b3, b2;     \
194         veor    a3, a3, a1;     veor    b3, b3, b1;     veor    a1, a1, a0;     veor    b1, b1, b0;     \
195         vorr    a1, a1, a2;     vorr    b1, b1, b2;     veor    a0, a0, a3;     veor    b0, b0, b3;     \
196         veor    a1, a1, a4;     veor    b1, b1, b4;\
197         veor    a0, a1;         veor    b0, b1;
198
199 #define SBOX4(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
200         veor    a1, a1, a3;     veor    b1, b1, b3;     vmvn    a3, a3;         vmvn    b3, b3;         \
201         veor    a2, a2, a3;     veor    b2, b2, b3;     veor    a3, a3, a0;     veor    b3, b3, b0;     \
202         vmov    a4, a1;         vmov    b4, b1;         vand    a1, a1, a3;     vand    b1, b1, b3;     \
203         veor    a1, a1, a2;     veor    b1, b1, b2;     veor    a4, a4, a3;     veor    b4, b4, b3;     \
204         veor    a0, a0, a4;     veor    b0, b0, b4;     vand    a2, a2, a4;     vand    b2, b2, b4;     \
205         veor    a2, a2, a0;     veor    b2, b2, b0;     vand    a0, a0, a1;     vand    b0, b0, b1;     \
206         veor    a3, a3, a0;     veor    b3, b3, b0;     vorr    a4, a4, a1;     vorr    b4, b4, b1;     \
207         veor    a4, a4, a0;     veor    b4, b4, b0;     vorr    a0, a0, a3;     vorr    b0, b0, b3;     \
208         veor    a0, a0, a2;     veor    b0, b0, b2;     vand    a2, a2, a3;     vand    b2, b2, b3;     \
209         vmvn    a0, a0;         vmvn    b0, b0;         veor    a4, a2;         veor    b4, b2;
210
211 #define SBOX4_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
212         vmov    a4, a2;         vmov    b4, b2;         vand    a2, a2, a3;     vand    b2, b2, b3;     \
213         veor    a2, a2, a1;     veor    b2, b2, b1;     vorr    a1, a1, a3;     vorr    b1, b1, b3;     \
214         vand    a1, a1, a0;     vand    b1, b1, b0;     veor    a4, a4, a2;     veor    b4, b4, b2;     \
215         veor    a4, a4, a1;     veor    b4, b4, b1;     vand    a1, a1, a2;     vand    b1, b1, b2;     \
216         vmvn    a0, a0;         vmvn    b0, b0;         veor    a3, a3, a4;     veor    b3, b3, b4;     \
217         veor    a1, a1, a3;     veor    b1, b1, b3;     vand    a3, a3, a0;     vand    b3, b3, b0;     \
218         veor    a3, a3, a2;     veor    b3, b3, b2;     veor    a0, a0, a1;     veor    b0, b0, b1;     \
219         vand    a2, a2, a0;     vand    b2, b2, b0;     veor    a3, a3, a0;     veor    b3, b3, b0;     \
220         veor    a2, a2, a4;     veor    b2, b2, b4;\
221         vorr    a2, a2, a3;     vorr    b2, b2, b3;     veor    a3, a3, a0;     veor    b3, b3, b0;     \
222         veor    a2, a1;         veor    b2, b1;
223
224 #define SBOX5(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
225         veor    a0, a0, a1;     veor    b0, b0, b1;     veor    a1, a1, a3;     veor    b1, b1, b3;     \
226         vmvn    a3, a3;         vmvn    b3, b3;         vmov    a4, a1;         vmov    b4, b1;         \
227         vand    a1, a1, a0;     vand    b1, b1, b0;     veor    a2, a2, a3;     veor    b2, b2, b3;     \
228         veor    a1, a1, a2;     veor    b1, b1, b2;     vorr    a2, a2, a4;     vorr    b2, b2, b4;     \
229         veor    a4, a4, a3;     veor    b4, b4, b3;     vand    a3, a3, a1;     vand    b3, b3, b1;     \
230         veor    a3, a3, a0;     veor    b3, b3, b0;     veor    a4, a4, a1;     veor    b4, b4, b1;     \
231         veor    a4, a4, a2;     veor    b4, b4, b2;     veor    a2, a2, a0;     veor    b2, b2, b0;     \
232         vand    a0, a0, a3;     vand    b0, b0, b3;     vmvn    a2, a2;         vmvn    b2, b2;         \
233         veor    a0, a0, a4;     veor    b0, b0, b4;     vorr    a4, a4, a3;     vorr    b4, b4, b3;     \
234         veor    a2, a4;         veor    b2, b4;
235
236 #define SBOX5_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
237         vmvn    a1, a1;         vmvn    b1, b1;         vmov    a4, a3;         vmov    b4, b3;         \
238         veor    a2, a2, a1;     veor    b2, b2, b1;     vorr    a3, a3, a0;     vorr    b3, b3, b0;     \
239         veor    a3, a3, a2;     veor    b3, b3, b2;     vorr    a2, a2, a1;     vorr    b2, b2, b1;     \
240         vand    a2, a2, a0;     vand    b2, b2, b0;     veor    a4, a4, a3;     veor    b4, b4, b3;     \
241         veor    a2, a2, a4;     veor    b2, b2, b4;     vorr    a4, a4, a0;     vorr    b4, b4, b0;     \
242         veor    a4, a4, a1;     veor    b4, b4, b1;     vand    a1, a1, a2;     vand    b1, b1, b2;     \
243         veor    a1, a1, a3;     veor    b1, b1, b3;     veor    a4, a4, a2;     veor    b4, b4, b2;     \
244         vand    a3, a3, a4;     vand    b3, b3, b4;     veor    a4, a4, a1;     veor    b4, b4, b1;     \
245         veor    a3, a3, a4;     veor    b3, b3, b4;     vmvn    a4, a4;         vmvn    b4, b4;         \
246         veor    a3, a0;         veor    b3, b0;
247
248 #define SBOX6(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
249         vmvn    a2, a2;         vmvn    b2, b2;         vmov    a4, a3;         vmov    b4, b3;         \
250         vand    a3, a3, a0;     vand    b3, b3, b0;     veor    a0, a0, a4;     veor    b0, b0, b4;     \
251         veor    a3, a3, a2;     veor    b3, b3, b2;     vorr    a2, a2, a4;     vorr    b2, b2, b4;     \
252         veor    a1, a1, a3;     veor    b1, b1, b3;     veor    a2, a2, a0;     veor    b2, b2, b0;     \
253         vorr    a0, a0, a1;     vorr    b0, b0, b1;     veor    a2, a2, a1;     veor    b2, b2, b1;     \
254         veor    a4, a4, a0;     veor    b4, b4, b0;     vorr    a0, a0, a3;     vorr    b0, b0, b3;     \
255         veor    a0, a0, a2;     veor    b0, b0, b2;     veor    a4, a4, a3;     veor    b4, b4, b3;     \
256         veor    a4, a4, a0;     veor    b4, b4, b0;     vmvn    a3, a3;         vmvn    b3, b3;         \
257         vand    a2, a2, a4;     vand    b2, b2, b4;\
258         veor    a2, a3;         veor    b2, b3;
259
260 #define SBOX6_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
261         veor    a0, a0, a2;     veor    b0, b0, b2;     vmov    a4, a2;         vmov    b4, b2;         \
262         vand    a2, a2, a0;     vand    b2, b2, b0;     veor    a4, a4, a3;     veor    b4, b4, b3;     \
263         vmvn    a2, a2;         vmvn    b2, b2;         veor    a3, a3, a1;     veor    b3, b3, b1;     \
264         veor    a2, a2, a3;     veor    b2, b2, b3;     vorr    a4, a4, a0;     vorr    b4, b4, b0;     \
265         veor    a0, a0, a2;     veor    b0, b0, b2;     veor    a3, a3, a4;     veor    b3, b3, b4;     \
266         veor    a4, a4, a1;     veor    b4, b4, b1;     vand    a1, a1, a3;     vand    b1, b1, b3;     \
267         veor    a1, a1, a0;     veor    b1, b1, b0;     veor    a0, a0, a3;     veor    b0, b0, b3;     \
268         vorr    a0, a0, a2;     vorr    b0, b0, b2;     veor    a3, a3, a1;     veor    b3, b3, b1;     \
269         veor    a4, a0;         veor    b4, b0;
270
271 #define SBOX7(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
272         vmov    a4, a1;         vmov    b4, b1;         vorr    a1, a1, a2;     vorr    b1, b1, b2;     \
273         veor    a1, a1, a3;     veor    b1, b1, b3;     veor    a4, a4, a2;     veor    b4, b4, b2;     \
274         veor    a2, a2, a1;     veor    b2, b2, b1;     vorr    a3, a3, a4;     vorr    b3, b3, b4;     \
275         vand    a3, a3, a0;     vand    b3, b3, b0;     veor    a4, a4, a2;     veor    b4, b4, b2;     \
276         veor    a3, a3, a1;     veor    b3, b3, b1;     vorr    a1, a1, a4;     vorr    b1, b1, b4;     \
277         veor    a1, a1, a0;     veor    b1, b1, b0;     vorr    a0, a0, a4;     vorr    b0, b0, b4;     \
278         veor    a0, a0, a2;     veor    b0, b0, b2;     veor    a1, a1, a4;     veor    b1, b1, b4;     \
279         veor    a2, a2, a1;     veor    b2, b2, b1;     vand    a1, a1, a0;     vand    b1, b1, b0;     \
280         veor    a1, a1, a4;     veor    b1, b1, b4;     vmvn    a2, a2;         vmvn    b2, b2;         \
281         vorr    a2, a2, a0;     vorr    b2, b2, b0;\
282         veor    a4, a2;         veor    b4, b2;
283
284 #define SBOX7_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
285         vmov    a4, a2;         vmov    b4, b2;         veor    a2, a2, a0;     veor    b2, b2, b0;     \
286         vand    a0, a0, a3;     vand    b0, b0, b3;     vorr    a4, a4, a3;     vorr    b4, b4, b3;     \
287         vmvn    a2, a2;         vmvn    b2, b2;         veor    a3, a3, a1;     veor    b3, b3, b1;     \
288         vorr    a1, a1, a0;     vorr    b1, b1, b0;     veor    a0, a0, a2;     veor    b0, b0, b2;     \
289         vand    a2, a2, a4;     vand    b2, b2, b4;     vand    a3, a3, a4;     vand    b3, b3, b4;     \
290         veor    a1, a1, a2;     veor    b1, b1, b2;     veor    a2, a2, a0;     veor    b2, b2, b0;     \
291         vorr    a0, a0, a2;     vorr    b0, b0, b2;     veor    a4, a4, a1;     veor    b4, b4, b1;     \
292         veor    a0, a0, a3;     veor    b0, b0, b3;     veor    a3, a3, a4;     veor    b3, b3, b4;     \
293         vorr    a4, a4, a0;     vorr    b4, b4, b0;     veor    a3, a3, a2;     veor    b3, b3, b2;     \
294         veor    a4, a2;         veor    b4, b2;
295
296 /* Apply SBOX number WHICH to to the block.  */
297 #define SBOX(which, a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
298         SBOX##which (a0, a1, a2, a3, a4, b0, b1, b2, b3, b4)
299
300 /* Apply inverse SBOX number WHICH to to the block.  */
301 #define SBOX_INVERSE(which, a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
302         SBOX##which##_INVERSE (a0, a1, a2, a3, a4, b0, b1, b2, b3, b4)
303
304 /* XOR round key into block state in a0,a1,a2,a3. a4 used as temporary.  */
305 #define BLOCK_XOR_KEY(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
306         vdup.32 RT3, RT0d0[0]; \
307         vdup.32 RT1, RT0d0[1]; \
308         vdup.32 RT2, RT0d1[0]; \
309         vdup.32 RT0, RT0d1[1]; \
310         veor a0, a0, RT3;       veor b0, b0, RT3; \
311         veor a1, a1, RT1;       veor b1, b1, RT1; \
312         veor a2, a2, RT2;       veor b2, b2, RT2; \
313         veor a3, a3, RT0;       veor b3, b3, RT0;
314
315 #define BLOCK_LOAD_KEY_ENC() \
316         vld1.8 {RT0d0, RT0d1}, [RROUND]!;
317
318 #define BLOCK_LOAD_KEY_DEC() \
319         vld1.8 {RT0d0, RT0d1}, [RROUND]; \
320         sub RROUND, RROUND, #16
321
322 /* Apply the linear transformation to BLOCK.  */
323 #define LINEAR_TRANSFORMATION(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
324         vshl.u32        a4, a0, #13;            vshl.u32        b4, b0, #13;            \
325         vshr.u32        a0, a0, #(32-13);       vshr.u32        b0, b0, #(32-13);       \
326         veor            a0, a0, a4;             veor            b0, b0, b4;             \
327         vshl.u32        a4, a2, #3;             vshl.u32        b4, b2, #3;             \
328         vshr.u32        a2, a2, #(32-3);        vshr.u32        b2, b2, #(32-3);        \
329         veor            a2, a2, a4;             veor            b2, b2, b4;             \
330         veor            a1, a0, a1;             veor            b1, b0, b1;             \
331         veor            a1, a2, a1;             veor            b1, b2, b1;             \
332         vshl.u32        a4, a0, #3;             vshl.u32        b4, b0, #3;             \
333         veor            a3, a2, a3;             veor            b3, b2, b3;             \
334         veor            a3, a4, a3;             veor            b3, b4, b3;             \
335         vshl.u32        a4, a1, #1;             vshl.u32        b4, b1, #1;             \
336         vshr.u32        a1, a1, #(32-1);        vshr.u32        b1, b1, #(32-1);        \
337         veor            a1, a1, a4;             veor            b1, b1, b4;             \
338         vshl.u32        a4, a3, #7;             vshl.u32        b4, b3, #7;             \
339         vshr.u32        a3, a3, #(32-7);        vshr.u32        b3, b3, #(32-7);        \
340         veor            a3, a3, a4;             veor            b3, b3, b4;             \
341         veor            a0, a1, a0;             veor            b0, b1, b0;             \
342         veor            a0, a3, a0;             veor            b0, b3, b0;             \
343         vshl.u32        a4, a1, #7;             vshl.u32        b4, b1, #7;             \
344         veor            a2, a3, a2;             veor            b2, b3, b2;             \
345         veor            a2, a4, a2;             veor            b2, b4, b2;             \
346         vshl.u32        a4, a0, #5;             vshl.u32        b4, b0, #5;             \
347         vshr.u32        a0, a0, #(32-5);        vshr.u32        b0, b0, #(32-5);        \
348         veor            a0, a0, a4;             veor            b0, b0, b4;             \
349         vshl.u32        a4, a2, #22;            vshl.u32        b4, b2, #22;            \
350         vshr.u32        a2, a2, #(32-22);       vshr.u32        b2, b2, #(32-22);       \
351         veor            a2, a2, a4;             veor            b2, b2, b4;
352
353 /* Apply the inverse linear transformation to BLOCK.  */
354 #define LINEAR_TRANSFORMATION_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
355         vshr.u32        a4, a2, #22;            vshr.u32        b4, b2, #22;            \
356         vshl.u32        a2, a2, #(32-22);       vshl.u32        b2, b2, #(32-22);       \
357         veor            a2, a2, a4;             veor            b2, b2, b4;             \
358         vshr.u32        a4, a0, #5;             vshr.u32        b4, b0, #5;             \
359         vshl.u32        a0, a0, #(32-5);        vshl.u32        b0, b0, #(32-5);        \
360         veor            a0, a0, a4;             veor            b0, b0, b4;             \
361         vshl.u32        a4, a1, #7;             vshl.u32        b4, b1, #7;             \
362         veor            a2, a3, a2;             veor            b2, b3, b2;             \
363         veor            a2, a4, a2;             veor            b2, b4, b2;             \
364         veor            a0, a1, a0;             veor            b0, b1, b0;             \
365         veor            a0, a3, a0;             veor            b0, b3, b0;             \
366         vshr.u32        a4, a3, #7;             vshr.u32        b4, b3, #7;             \
367         vshl.u32        a3, a3, #(32-7);        vshl.u32        b3, b3, #(32-7);        \
368         veor            a3, a3, a4;             veor            b3, b3, b4;             \
369         vshr.u32        a4, a1, #1;             vshr.u32        b4, b1, #1;             \
370         vshl.u32        a1, a1, #(32-1);        vshl.u32        b1, b1, #(32-1);        \
371         veor            a1, a1, a4;             veor            b1, b1, b4;             \
372         vshl.u32        a4, a0, #3;             vshl.u32        b4, b0, #3;             \
373         veor            a3, a2, a3;             veor            b3, b2, b3;             \
374         veor            a3, a4, a3;             veor            b3, b4, b3;             \
375         veor            a1, a0, a1;             veor            b1, b0, b1;             \
376         veor            a1, a2, a1;             veor            b1, b2, b1;             \
377         vshr.u32        a4, a2, #3;             vshr.u32        b4, b2, #3;             \
378         vshl.u32        a2, a2, #(32-3);        vshl.u32        b2, b2, #(32-3);        \
379         veor            a2, a2, a4;             veor            b2, b2, b4;             \
380         vshr.u32        a4, a0, #13;            vshr.u32        b4, b0, #13;            \
381         vshl.u32        a0, a0, #(32-13);       vshl.u32        b0, b0, #(32-13);       \
382         veor            a0, a0, a4;             veor            b0, b0, b4;
383
384 /* Apply a Serpent round to eight parallel blocks.  This macro increments
385    `round'.  */
386 #define ROUND(round, which, a0, a1, a2, a3, a4, na0, na1, na2, na3, na4, \
387                             b0, b1, b2, b3, b4, nb0, nb1, nb2, nb3, nb4) \
388         BLOCK_XOR_KEY (a0, a1, a2, a3, a4, b0, b1, b2, b3, b4);         \
389         BLOCK_LOAD_KEY_ENC ();                                          \
390         SBOX (which, a0, a1, a2, a3, a4, b0, b1, b2, b3, b4);           \
391         LINEAR_TRANSFORMATION (na0, na1, na2, na3, na4, nb0, nb1, nb2, nb3, nb4);
392
393 /* Apply the last Serpent round to eight parallel blocks.  This macro increments
394    `round'.  */
395 #define ROUND_LAST(round, which, a0, a1, a2, a3, a4, na0, na1, na2, na3, na4, \
396                                  b0, b1, b2, b3, b4, nb0, nb1, nb2, nb3, nb4) \
397         BLOCK_XOR_KEY (a0, a1, a2, a3, a4, b0, b1, b2, b3, b4);         \
398         BLOCK_LOAD_KEY_ENC ();                                          \
399         SBOX (which, a0, a1, a2, a3, a4, b0, b1, b2, b3, b4);           \
400         BLOCK_XOR_KEY (na0, na1, na2, na3, na4, nb0, nb1, nb2, nb3, nb4);
401
402 /* Apply an inverse Serpent round to eight parallel blocks.  This macro
403    increments `round'.  */
404 #define ROUND_INVERSE(round, which, a0, a1, a2, a3, a4, \
405                                     na0, na1, na2, na3, na4, \
406                                     b0, b1, b2, b3, b4, \
407                                     nb0, nb1, nb2, nb3, nb4) \
408         LINEAR_TRANSFORMATION_INVERSE (a0, a1, a2, a3, a4, b0, b1, b2, b3, b4); \
409         SBOX_INVERSE (which, a0, a1, a2, a3, a4, b0, b1, b2, b3, b4);           \
410         BLOCK_XOR_KEY (na0, na1, na2, na3, na4, nb0, nb1, nb2, nb3, nb4);       \
411         BLOCK_LOAD_KEY_DEC ();
412
413 /* Apply the first inverse Serpent round to eight parallel blocks.  This macro
414    increments `round'.  */
415 #define ROUND_FIRST_INVERSE(round, which, a0, a1, a2, a3, a4, \
416                                           na0, na1, na2, na3, na4, \
417                                           b0, b1, b2, b3, b4, \
418                                           nb0, nb1, nb2, nb3, nb4) \
419         BLOCK_XOR_KEY (a0, a1, a2, a3, a4, b0, b1, b2, b3, b4);                 \
420         BLOCK_LOAD_KEY_DEC ();                                                  \
421         SBOX_INVERSE (which, a0, a1, a2, a3, a4, b0, b1, b2, b3, b4);           \
422         BLOCK_XOR_KEY (na0, na1, na2, na3, na4, nb0, nb1, nb2, nb3, nb4);       \
423         BLOCK_LOAD_KEY_DEC ();
424
425 .align 3
426 .type __serpent_enc_blk8,%function;
427 __serpent_enc_blk8:
428         /* input:
429          *      r0: round key pointer
430          *      RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: eight parallel plaintext
431          *                                              blocks
432          * output:
433          *      RA4, RA1, RA2, RA0, RB4, RB1, RB2, RB0: eight parallel
434          *                                              ciphertext blocks
435          */
436
437         transpose_4x4(RA0, RA1, RA2, RA3);
438         BLOCK_LOAD_KEY_ENC ();
439         transpose_4x4(RB0, RB1, RB2, RB3);
440
441         ROUND (0, 0, RA0, RA1, RA2, RA3, RA4, RA1, RA4, RA2, RA0, RA3,
442                      RB0, RB1, RB2, RB3, RB4, RB1, RB4, RB2, RB0, RB3);
443         ROUND (1, 1, RA1, RA4, RA2, RA0, RA3, RA2, RA1, RA0, RA4, RA3,
444                      RB1, RB4, RB2, RB0, RB3, RB2, RB1, RB0, RB4, RB3);
445         ROUND (2, 2, RA2, RA1, RA0, RA4, RA3, RA0, RA4, RA1, RA3, RA2,
446                      RB2, RB1, RB0, RB4, RB3, RB0, RB4, RB1, RB3, RB2);
447         ROUND (3, 3, RA0, RA4, RA1, RA3, RA2, RA4, RA1, RA3, RA2, RA0,
448                      RB0, RB4, RB1, RB3, RB2, RB4, RB1, RB3, RB2, RB0);
449         ROUND (4, 4, RA4, RA1, RA3, RA2, RA0, RA1, RA0, RA4, RA2, RA3,
450                      RB4, RB1, RB3, RB2, RB0, RB1, RB0, RB4, RB2, RB3);
451         ROUND (5, 5, RA1, RA0, RA4, RA2, RA3, RA0, RA2, RA1, RA4, RA3,
452                      RB1, RB0, RB4, RB2, RB3, RB0, RB2, RB1, RB4, RB3);
453         ROUND (6, 6, RA0, RA2, RA1, RA4, RA3, RA0, RA2, RA3, RA1, RA4,
454                      RB0, RB2, RB1, RB4, RB3, RB0, RB2, RB3, RB1, RB4);
455         ROUND (7, 7, RA0, RA2, RA3, RA1, RA4, RA4, RA1, RA2, RA0, RA3,
456                      RB0, RB2, RB3, RB1, RB4, RB4, RB1, RB2, RB0, RB3);
457         ROUND (8, 0, RA4, RA1, RA2, RA0, RA3, RA1, RA3, RA2, RA4, RA0,
458                      RB4, RB1, RB2, RB0, RB3, RB1, RB3, RB2, RB4, RB0);
459         ROUND (9, 1, RA1, RA3, RA2, RA4, RA0, RA2, RA1, RA4, RA3, RA0,
460                      RB1, RB3, RB2, RB4, RB0, RB2, RB1, RB4, RB3, RB0);
461         ROUND (10, 2, RA2, RA1, RA4, RA3, RA0, RA4, RA3, RA1, RA0, RA2,
462                       RB2, RB1, RB4, RB3, RB0, RB4, RB3, RB1, RB0, RB2);
463         ROUND (11, 3, RA4, RA3, RA1, RA0, RA2, RA3, RA1, RA0, RA2, RA4,
464                       RB4, RB3, RB1, RB0, RB2, RB3, RB1, RB0, RB2, RB4);
465         ROUND (12, 4, RA3, RA1, RA0, RA2, RA4, RA1, RA4, RA3, RA2, RA0,
466                       RB3, RB1, RB0, RB2, RB4, RB1, RB4, RB3, RB2, RB0);
467         ROUND (13, 5, RA1, RA4, RA3, RA2, RA0, RA4, RA2, RA1, RA3, RA0,
468                       RB1, RB4, RB3, RB2, RB0, RB4, RB2, RB1, RB3, RB0);
469         ROUND (14, 6, RA4, RA2, RA1, RA3, RA0, RA4, RA2, RA0, RA1, RA3,
470                       RB4, RB2, RB1, RB3, RB0, RB4, RB2, RB0, RB1, RB3);
471         ROUND (15, 7, RA4, RA2, RA0, RA1, RA3, RA3, RA1, RA2, RA4, RA0,
472                       RB4, RB2, RB0, RB1, RB3, RB3, RB1, RB2, RB4, RB0);
473         ROUND (16, 0, RA3, RA1, RA2, RA4, RA0, RA1, RA0, RA2, RA3, RA4,
474                       RB3, RB1, RB2, RB4, RB0, RB1, RB0, RB2, RB3, RB4);
475         ROUND (17, 1, RA1, RA0, RA2, RA3, RA4, RA2, RA1, RA3, RA0, RA4,
476                       RB1, RB0, RB2, RB3, RB4, RB2, RB1, RB3, RB0, RB4);
477         ROUND (18, 2, RA2, RA1, RA3, RA0, RA4, RA3, RA0, RA1, RA4, RA2,
478                       RB2, RB1, RB3, RB0, RB4, RB3, RB0, RB1, RB4, RB2);
479         ROUND (19, 3, RA3, RA0, RA1, RA4, RA2, RA0, RA1, RA4, RA2, RA3,
480                       RB3, RB0, RB1, RB4, RB2, RB0, RB1, RB4, RB2, RB3);
481         ROUND (20, 4, RA0, RA1, RA4, RA2, RA3, RA1, RA3, RA0, RA2, RA4,
482                       RB0, RB1, RB4, RB2, RB3, RB1, RB3, RB0, RB2, RB4);
483         ROUND (21, 5, RA1, RA3, RA0, RA2, RA4, RA3, RA2, RA1, RA0, RA4,
484                       RB1, RB3, RB0, RB2, RB4, RB3, RB2, RB1, RB0, RB4);
485         ROUND (22, 6, RA3, RA2, RA1, RA0, RA4, RA3, RA2, RA4, RA1, RA0,
486                       RB3, RB2, RB1, RB0, RB4, RB3, RB2, RB4, RB1, RB0);
487         ROUND (23, 7, RA3, RA2, RA4, RA1, RA0, RA0, RA1, RA2, RA3, RA4,
488                       RB3, RB2, RB4, RB1, RB0, RB0, RB1, RB2, RB3, RB4);
489         ROUND (24, 0, RA0, RA1, RA2, RA3, RA4, RA1, RA4, RA2, RA0, RA3,
490                       RB0, RB1, RB2, RB3, RB4, RB1, RB4, RB2, RB0, RB3);
491         ROUND (25, 1, RA1, RA4, RA2, RA0, RA3, RA2, RA1, RA0, RA4, RA3,
492                       RB1, RB4, RB2, RB0, RB3, RB2, RB1, RB0, RB4, RB3);
493         ROUND (26, 2, RA2, RA1, RA0, RA4, RA3, RA0, RA4, RA1, RA3, RA2,
494                       RB2, RB1, RB0, RB4, RB3, RB0, RB4, RB1, RB3, RB2);
495         ROUND (27, 3, RA0, RA4, RA1, RA3, RA2, RA4, RA1, RA3, RA2, RA0,
496                       RB0, RB4, RB1, RB3, RB2, RB4, RB1, RB3, RB2, RB0);
497         ROUND (28, 4, RA4, RA1, RA3, RA2, RA0, RA1, RA0, RA4, RA2, RA3,
498                       RB4, RB1, RB3, RB2, RB0, RB1, RB0, RB4, RB2, RB3);
499         ROUND (29, 5, RA1, RA0, RA4, RA2, RA3, RA0, RA2, RA1, RA4, RA3,
500                       RB1, RB0, RB4, RB2, RB3, RB0, RB2, RB1, RB4, RB3);
501         ROUND (30, 6, RA0, RA2, RA1, RA4, RA3, RA0, RA2, RA3, RA1, RA4,
502                       RB0, RB2, RB1, RB4, RB3, RB0, RB2, RB3, RB1, RB4);
503         ROUND_LAST (31, 7, RA0, RA2, RA3, RA1, RA4, RA4, RA1, RA2, RA0, RA3,
504                            RB0, RB2, RB3, RB1, RB4, RB4, RB1, RB2, RB0, RB3);
505
506         transpose_4x4(RA4, RA1, RA2, RA0);
507         transpose_4x4(RB4, RB1, RB2, RB0);
508
509         bx lr;
510 .size __serpent_enc_blk8,.-__serpent_enc_blk8;
511
512 .align 3
513 .type   __serpent_dec_blk8,%function;
514 __serpent_dec_blk8:
515         /* input:
516          *      r0: round key pointer
517          *      RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: eight parallel
518          *                                              ciphertext blocks
519          * output:
520          *      RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: eight parallel plaintext
521          *                                              blocks
522          */
523
524         add RROUND, RROUND, #(32*16);
525
526         transpose_4x4(RA0, RA1, RA2, RA3);
527         BLOCK_LOAD_KEY_DEC ();
528         transpose_4x4(RB0, RB1, RB2, RB3);
529
530         ROUND_FIRST_INVERSE (31, 7, RA0, RA1, RA2, RA3, RA4,
531                                     RA3, RA0, RA1, RA4, RA2,
532                                     RB0, RB1, RB2, RB3, RB4,
533                                     RB3, RB0, RB1, RB4, RB2);
534         ROUND_INVERSE (30, 6, RA3, RA0, RA1, RA4, RA2, RA0, RA1, RA2, RA4, RA3,
535                               RB3, RB0, RB1, RB4, RB2, RB0, RB1, RB2, RB4, RB3);
536         ROUND_INVERSE (29, 5, RA0, RA1, RA2, RA4, RA3, RA1, RA3, RA4, RA2, RA0,
537                               RB0, RB1, RB2, RB4, RB3, RB1, RB3, RB4, RB2, RB0);
538         ROUND_INVERSE (28, 4, RA1, RA3, RA4, RA2, RA0, RA1, RA2, RA4, RA0, RA3,
539                               RB1, RB3, RB4, RB2, RB0, RB1, RB2, RB4, RB0, RB3);
540         ROUND_INVERSE (27, 3, RA1, RA2, RA4, RA0, RA3, RA4, RA2, RA0, RA1, RA3,
541                               RB1, RB2, RB4, RB0, RB3, RB4, RB2, RB0, RB1, RB3);
542         ROUND_INVERSE (26, 2, RA4, RA2, RA0, RA1, RA3, RA2, RA3, RA0, RA1, RA4,
543                               RB4, RB2, RB0, RB1, RB3, RB2, RB3, RB0, RB1, RB4);
544         ROUND_INVERSE (25, 1, RA2, RA3, RA0, RA1, RA4, RA4, RA2, RA1, RA0, RA3,
545                               RB2, RB3, RB0, RB1, RB4, RB4, RB2, RB1, RB0, RB3);
546         ROUND_INVERSE (24, 0, RA4, RA2, RA1, RA0, RA3, RA4, RA3, RA2, RA0, RA1,
547                               RB4, RB2, RB1, RB0, RB3, RB4, RB3, RB2, RB0, RB1);
548         ROUND_INVERSE (23, 7, RA4, RA3, RA2, RA0, RA1, RA0, RA4, RA3, RA1, RA2,
549                               RB4, RB3, RB2, RB0, RB1, RB0, RB4, RB3, RB1, RB2);
550         ROUND_INVERSE (22, 6, RA0, RA4, RA3, RA1, RA2, RA4, RA3, RA2, RA1, RA0,
551                               RB0, RB4, RB3, RB1, RB2, RB4, RB3, RB2, RB1, RB0);
552         ROUND_INVERSE (21, 5, RA4, RA3, RA2, RA1, RA0, RA3, RA0, RA1, RA2, RA4,
553                               RB4, RB3, RB2, RB1, RB0, RB3, RB0, RB1, RB2, RB4);
554         ROUND_INVERSE (20, 4, RA3, RA0, RA1, RA2, RA4, RA3, RA2, RA1, RA4, RA0,
555                               RB3, RB0, RB1, RB2, RB4, RB3, RB2, RB1, RB4, RB0);
556         ROUND_INVERSE (19, 3, RA3, RA2, RA1, RA4, RA0, RA1, RA2, RA4, RA3, RA0,
557                               RB3, RB2, RB1, RB4, RB0, RB1, RB2, RB4, RB3, RB0);
558         ROUND_INVERSE (18, 2, RA1, RA2, RA4, RA3, RA0, RA2, RA0, RA4, RA3, RA1,
559                               RB1, RB2, RB4, RB3, RB0, RB2, RB0, RB4, RB3, RB1);
560         ROUND_INVERSE (17, 1, RA2, RA0, RA4, RA3, RA1, RA1, RA2, RA3, RA4, RA0,
561                               RB2, RB0, RB4, RB3, RB1, RB1, RB2, RB3, RB4, RB0);
562         ROUND_INVERSE (16, 0, RA1, RA2, RA3, RA4, RA0, RA1, RA0, RA2, RA4, RA3,
563                               RB1, RB2, RB3, RB4, RB0, RB1, RB0, RB2, RB4, RB3);
564         ROUND_INVERSE (15, 7, RA1, RA0, RA2, RA4, RA3, RA4, RA1, RA0, RA3, RA2,
565                               RB1, RB0, RB2, RB4, RB3, RB4, RB1, RB0, RB3, RB2);
566         ROUND_INVERSE (14, 6, RA4, RA1, RA0, RA3, RA2, RA1, RA0, RA2, RA3, RA4,
567                               RB4, RB1, RB0, RB3, RB2, RB1, RB0, RB2, RB3, RB4);
568         ROUND_INVERSE (13, 5, RA1, RA0, RA2, RA3, RA4, RA0, RA4, RA3, RA2, RA1,
569                               RB1, RB0, RB2, RB3, RB4, RB0, RB4, RB3, RB2, RB1);
570         ROUND_INVERSE (12, 4, RA0, RA4, RA3, RA2, RA1, RA0, RA2, RA3, RA1, RA4,
571                               RB0, RB4, RB3, RB2, RB1, RB0, RB2, RB3, RB1, RB4);
572         ROUND_INVERSE (11, 3, RA0, RA2, RA3, RA1, RA4, RA3, RA2, RA1, RA0, RA4,
573                               RB0, RB2, RB3, RB1, RB4, RB3, RB2, RB1, RB0, RB4);
574         ROUND_INVERSE (10, 2, RA3, RA2, RA1, RA0, RA4, RA2, RA4, RA1, RA0, RA3,
575                               RB3, RB2, RB1, RB0, RB4, RB2, RB4, RB1, RB0, RB3);
576         ROUND_INVERSE (9, 1, RA2, RA4, RA1, RA0, RA3, RA3, RA2, RA0, RA1, RA4,
577                              RB2, RB4, RB1, RB0, RB3, RB3, RB2, RB0, RB1, RB4);
578         ROUND_INVERSE (8, 0, RA3, RA2, RA0, RA1, RA4, RA3, RA4, RA2, RA1, RA0,
579                              RB3, RB2, RB0, RB1, RB4, RB3, RB4, RB2, RB1, RB0);
580         ROUND_INVERSE (7, 7, RA3, RA4, RA2, RA1, RA0, RA1, RA3, RA4, RA0, RA2,
581                              RB3, RB4, RB2, RB1, RB0, RB1, RB3, RB4, RB0, RB2);
582         ROUND_INVERSE (6, 6, RA1, RA3, RA4, RA0, RA2, RA3, RA4, RA2, RA0, RA1,
583                              RB1, RB3, RB4, RB0, RB2, RB3, RB4, RB2, RB0, RB1);
584         ROUND_INVERSE (5, 5, RA3, RA4, RA2, RA0, RA1, RA4, RA1, RA0, RA2, RA3,
585                              RB3, RB4, RB2, RB0, RB1, RB4, RB1, RB0, RB2, RB3);
586         ROUND_INVERSE (4, 4, RA4, RA1, RA0, RA2, RA3, RA4, RA2, RA0, RA3, RA1,
587                              RB4, RB1, RB0, RB2, RB3, RB4, RB2, RB0, RB3, RB1);
588         ROUND_INVERSE (3, 3, RA4, RA2, RA0, RA3, RA1, RA0, RA2, RA3, RA4, RA1,
589                              RB4, RB2, RB0, RB3, RB1, RB0, RB2, RB3, RB4, RB1);
590         ROUND_INVERSE (2, 2, RA0, RA2, RA3, RA4, RA1, RA2, RA1, RA3, RA4, RA0,
591                              RB0, RB2, RB3, RB4, RB1, RB2, RB1, RB3, RB4, RB0);
592         ROUND_INVERSE (1, 1, RA2, RA1, RA3, RA4, RA0, RA0, RA2, RA4, RA3, RA1,
593                              RB2, RB1, RB3, RB4, RB0, RB0, RB2, RB4, RB3, RB1);
594         ROUND_INVERSE (0, 0, RA0, RA2, RA4, RA3, RA1, RA0, RA1, RA2, RA3, RA4,
595                              RB0, RB2, RB4, RB3, RB1, RB0, RB1, RB2, RB3, RB4);
596
597         transpose_4x4(RA0, RA1, RA2, RA3);
598         transpose_4x4(RB0, RB1, RB2, RB3);
599
600         bx lr;
601 .size __serpent_dec_blk8,.-__serpent_dec_blk8;
602
603 .align 3
604 .globl _gcry_serpent_neon_ctr_enc
605 .type _gcry_serpent_neon_ctr_enc,%function;
606 _gcry_serpent_neon_ctr_enc:
607         /* input:
608          *      r0: ctx, CTX
609          *      r1: dst (8 blocks)
610          *      r2: src (8 blocks)
611          *      r3: iv
612          */
613
614         vmov.u8 RT1d0, #0xff; /* u64: -1 */
615         push {r4,lr};
616         vadd.u64 RT2d0, RT1d0, RT1d0; /* u64: -2 */
617         vpush {RA4-RB2};
618
619         /* load IV and byteswap */
620         vld1.8 {RA0}, [r3];
621         vrev64.u8 RT0, RA0; /* be => le */
622         ldr r4, [r3, #8];
623
624         /* construct IVs */
625         vsub.u64 RA2d1, RT0d1, RT2d0; /* +2 */
626         vsub.u64 RA1d1, RT0d1, RT1d0; /* +1 */
627         cmp r4, #-1;
628
629         vsub.u64 RB0d1, RA2d1, RT2d0; /* +4 */
630         vsub.u64 RA3d1, RA2d1, RT1d0; /* +3 */
631         ldr r4, [r3, #12];
632
633         vsub.u64 RB2d1, RB0d1, RT2d0; /* +6 */
634         vsub.u64 RB1d1, RB0d1, RT1d0; /* +5 */
635
636         vsub.u64 RT2d1, RB2d1, RT2d0; /* +8 */
637         vsub.u64 RB3d1, RB2d1, RT1d0; /* +7 */
638
639         vmov RA1d0, RT0d0;
640         vmov RA2d0, RT0d0;
641         vmov RA3d0, RT0d0;
642         vmov RB0d0, RT0d0;
643         rev r4, r4;
644         vmov RB1d0, RT0d0;
645         vmov RB2d0, RT0d0;
646         vmov RB3d0, RT0d0;
647         vmov RT2d0, RT0d0;
648
649         /* check need for handling 64-bit overflow and carry */
650         beq .Ldo_ctr_carry;
651
652 .Lctr_carry_done:
653         /* le => be */
654         vrev64.u8 RA1, RA1;
655         vrev64.u8 RA2, RA2;
656         vrev64.u8 RA3, RA3;
657         vrev64.u8 RB0, RB0;
658         vrev64.u8 RT2, RT2;
659         vrev64.u8 RB1, RB1;
660         vrev64.u8 RB2, RB2;
661         vrev64.u8 RB3, RB3;
662         /* store new IV */
663         vst1.8 {RT2}, [r3];
664
665         bl __serpent_enc_blk8;
666
667         vld1.8 {RT0, RT1}, [r2]!;
668         vld1.8 {RT2, RT3}, [r2]!;
669         veor RA4, RA4, RT0;
670         veor RA1, RA1, RT1;
671         vld1.8 {RT0, RT1}, [r2]!;
672         veor RA2, RA2, RT2;
673         veor RA0, RA0, RT3;
674         vld1.8 {RT2, RT3}, [r2]!;
675         veor RB4, RB4, RT0;
676         veor RT0, RT0;
677         veor RB1, RB1, RT1;
678         veor RT1, RT1;
679         veor RB2, RB2, RT2;
680         veor RT2, RT2;
681         veor RB0, RB0, RT3;
682         veor RT3, RT3;
683
684         vst1.8 {RA4}, [r1]!;
685         vst1.8 {RA1}, [r1]!;
686         veor RA1, RA1;
687         vst1.8 {RA2}, [r1]!;
688         veor RA2, RA2;
689         vst1.8 {RA0}, [r1]!;
690         veor RA0, RA0;
691         vst1.8 {RB4}, [r1]!;
692         veor RB4, RB4;
693         vst1.8 {RB1}, [r1]!;
694         vst1.8 {RB2}, [r1]!;
695         vst1.8 {RB0}, [r1]!;
696
697         vpop {RA4-RB2};
698
699         /* clear the used registers */
700         veor RA3, RA3;
701         veor RB3, RB3;
702
703         pop {r4,pc};
704
705 .Ldo_ctr_carry:
706         cmp r4, #-8;
707         blo .Lctr_carry_done;
708         beq .Lcarry_RT2;
709
710         cmp r4, #-6;
711         blo .Lcarry_RB3;
712         beq .Lcarry_RB2;
713
714         cmp r4, #-4;
715         blo .Lcarry_RB1;
716         beq .Lcarry_RB0;
717
718         cmp r4, #-2;
719         blo .Lcarry_RA3;
720         beq .Lcarry_RA2;
721
722         vsub.u64 RA1d0, RT1d0;
723 .Lcarry_RA2:
724         vsub.u64 RA2d0, RT1d0;
725 .Lcarry_RA3:
726         vsub.u64 RA3d0, RT1d0;
727 .Lcarry_RB0:
728         vsub.u64 RB0d0, RT1d0;
729 .Lcarry_RB1:
730         vsub.u64 RB1d0, RT1d0;
731 .Lcarry_RB2:
732         vsub.u64 RB2d0, RT1d0;
733 .Lcarry_RB3:
734         vsub.u64 RB3d0, RT1d0;
735 .Lcarry_RT2:
736         vsub.u64 RT2d0, RT1d0;
737
738         b .Lctr_carry_done;
739 .size _gcry_serpent_neon_ctr_enc,.-_gcry_serpent_neon_ctr_enc;
740
741 .align 3
742 .globl _gcry_serpent_neon_cfb_dec
743 .type _gcry_serpent_neon_cfb_dec,%function;
744 _gcry_serpent_neon_cfb_dec:
745         /* input:
746          *      r0: ctx, CTX
747          *      r1: dst (8 blocks)
748          *      r2: src (8 blocks)
749          *      r3: iv
750          */
751
752         push {lr};
753         vpush {RA4-RB2};
754
755         /* Load input */
756         vld1.8 {RA0}, [r3];
757         vld1.8 {RA1, RA2}, [r2]!;
758         vld1.8 {RA3}, [r2]!;
759         vld1.8 {RB0}, [r2]!;
760         vld1.8 {RB1, RB2}, [r2]!;
761         vld1.8 {RB3}, [r2]!;
762
763         /* Update IV */
764         vld1.8 {RT0}, [r2]!;
765         vst1.8 {RT0}, [r3];
766         mov r3, lr;
767         sub r2, r2, #(8*16);
768
769         bl __serpent_enc_blk8;
770
771         vld1.8 {RT0, RT1}, [r2]!;
772         vld1.8 {RT2, RT3}, [r2]!;
773         veor RA4, RA4, RT0;
774         veor RA1, RA1, RT1;
775         vld1.8 {RT0, RT1}, [r2]!;
776         veor RA2, RA2, RT2;
777         veor RA0, RA0, RT3;
778         vld1.8 {RT2, RT3}, [r2]!;
779         veor RB4, RB4, RT0;
780         veor RT0, RT0;
781         veor RB1, RB1, RT1;
782         veor RT1, RT1;
783         veor RB2, RB2, RT2;
784         veor RT2, RT2;
785         veor RB0, RB0, RT3;
786         veor RT3, RT3;
787
788         vst1.8 {RA4}, [r1]!;
789         vst1.8 {RA1}, [r1]!;
790         veor RA1, RA1;
791         vst1.8 {RA2}, [r1]!;
792         veor RA2, RA2;
793         vst1.8 {RA0}, [r1]!;
794         veor RA0, RA0;
795         vst1.8 {RB4}, [r1]!;
796         veor RB4, RB4;
797         vst1.8 {RB1}, [r1]!;
798         vst1.8 {RB2}, [r1]!;
799         vst1.8 {RB0}, [r1]!;
800
801         vpop {RA4-RB2};
802
803         /* clear the used registers */
804         veor RA3, RA3;
805         veor RB3, RB3;
806
807         pop {pc};
808 .size _gcry_serpent_neon_cfb_dec,.-_gcry_serpent_neon_cfb_dec;
809
810 .align 3
811 .globl _gcry_serpent_neon_cbc_dec
812 .type _gcry_serpent_neon_cbc_dec,%function;
813 _gcry_serpent_neon_cbc_dec:
814         /* input:
815          *      r0: ctx, CTX
816          *      r1: dst (8 blocks)
817          *      r2: src (8 blocks)
818          *      r3: iv
819          */
820
821         push {lr};
822         vpush {RA4-RB2};
823
824         vld1.8 {RA0, RA1}, [r2]!;
825         vld1.8 {RA2, RA3}, [r2]!;
826         vld1.8 {RB0, RB1}, [r2]!;
827         vld1.8 {RB2, RB3}, [r2]!;
828         sub r2, r2, #(8*16);
829
830         bl __serpent_dec_blk8;
831
832         vld1.8 {RB4}, [r3];
833         vld1.8 {RT0, RT1}, [r2]!;
834         vld1.8 {RT2, RT3}, [r2]!;
835         veor RA0, RA0, RB4;
836         veor RA1, RA1, RT0;
837         veor RA2, RA2, RT1;
838         vld1.8 {RT0, RT1}, [r2]!;
839         veor RA3, RA3, RT2;
840         veor RB0, RB0, RT3;
841         vld1.8 {RT2, RT3}, [r2]!;
842         veor RB1, RB1, RT0;
843         veor RT0, RT0;
844         veor RB2, RB2, RT1;
845         veor RT1, RT1;
846         veor RB3, RB3, RT2;
847         veor RT2, RT2;
848         vst1.8 {RT3}, [r3]; /* store new IV */
849         veor RT3, RT3;
850
851         vst1.8 {RA0, RA1}, [r1]!;
852         veor RA0, RA0;
853         veor RA1, RA1;
854         vst1.8 {RA2, RA3}, [r1]!;
855         veor RA2, RA2;
856         vst1.8 {RB0, RB1}, [r1]!;
857         veor RA3, RA3;
858         vst1.8 {RB2, RB3}, [r1]!;
859         veor RB3, RB3;
860
861         vpop {RA4-RB2};
862
863         /* clear the used registers */
864         veor RB4, RB4;
865
866         pop {pc};
867 .size _gcry_serpent_neon_cbc_dec,.-_gcry_serpent_neon_cbc_dec;
868
869 #endif