GNU Linux-libre 5.19-rc6-gnu
[releases.git] / arch / arm / crypto / aes-neonbs-core.S
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Bit sliced AES using NEON instructions
4  *
5  * Copyright (C) 2017 Linaro Ltd.
6  * Author: Ard Biesheuvel <ard.biesheuvel@linaro.org>
7  */
8
9 /*
10  * The algorithm implemented here is described in detail by the paper
11  * 'Faster and Timing-Attack Resistant AES-GCM' by Emilia Kaesper and
12  * Peter Schwabe (https://eprint.iacr.org/2009/129.pdf)
13  *
14  * This implementation is based primarily on the OpenSSL implementation
15  * for 32-bit ARM written by Andy Polyakov <appro@openssl.org>
16  */
17
18 #include <linux/linkage.h>
19 #include <asm/assembler.h>
20
21         .text
22         .fpu            neon
23
24         rounds          .req    ip
25         bskey           .req    r4
26
27         q0l             .req    d0
28         q0h             .req    d1
29         q1l             .req    d2
30         q1h             .req    d3
31         q2l             .req    d4
32         q2h             .req    d5
33         q3l             .req    d6
34         q3h             .req    d7
35         q4l             .req    d8
36         q4h             .req    d9
37         q5l             .req    d10
38         q5h             .req    d11
39         q6l             .req    d12
40         q6h             .req    d13
41         q7l             .req    d14
42         q7h             .req    d15
43         q8l             .req    d16
44         q8h             .req    d17
45         q9l             .req    d18
46         q9h             .req    d19
47         q10l            .req    d20
48         q10h            .req    d21
49         q11l            .req    d22
50         q11h            .req    d23
51         q12l            .req    d24
52         q12h            .req    d25
53         q13l            .req    d26
54         q13h            .req    d27
55         q14l            .req    d28
56         q14h            .req    d29
57         q15l            .req    d30
58         q15h            .req    d31
59
60         .macro          __tbl, out, tbl, in, tmp
61         .ifc            \out, \tbl
62         .ifb            \tmp
63         .error          __tbl needs temp register if out == tbl
64         .endif
65         vmov            \tmp, \out
66         .endif
67         vtbl.8          \out\()l, {\tbl}, \in\()l
68         .ifc            \out, \tbl
69         vtbl.8          \out\()h, {\tmp}, \in\()h
70         .else
71         vtbl.8          \out\()h, {\tbl}, \in\()h
72         .endif
73         .endm
74
75         .macro          __ldr, out, sym
76         vldr            \out\()l, \sym
77         vldr            \out\()h, \sym + 8
78         .endm
79
80         .macro          in_bs_ch, b0, b1, b2, b3, b4, b5, b6, b7
81         veor            \b2, \b2, \b1
82         veor            \b5, \b5, \b6
83         veor            \b3, \b3, \b0
84         veor            \b6, \b6, \b2
85         veor            \b5, \b5, \b0
86         veor            \b6, \b6, \b3
87         veor            \b3, \b3, \b7
88         veor            \b7, \b7, \b5
89         veor            \b3, \b3, \b4
90         veor            \b4, \b4, \b5
91         veor            \b2, \b2, \b7
92         veor            \b3, \b3, \b1
93         veor            \b1, \b1, \b5
94         .endm
95
96         .macro          out_bs_ch, b0, b1, b2, b3, b4, b5, b6, b7
97         veor            \b0, \b0, \b6
98         veor            \b1, \b1, \b4
99         veor            \b4, \b4, \b6
100         veor            \b2, \b2, \b0
101         veor            \b6, \b6, \b1
102         veor            \b1, \b1, \b5
103         veor            \b5, \b5, \b3
104         veor            \b3, \b3, \b7
105         veor            \b7, \b7, \b5
106         veor            \b2, \b2, \b5
107         veor            \b4, \b4, \b7
108         .endm
109
110         .macro          inv_in_bs_ch, b6, b1, b2, b4, b7, b0, b3, b5
111         veor            \b1, \b1, \b7
112         veor            \b4, \b4, \b7
113         veor            \b7, \b7, \b5
114         veor            \b1, \b1, \b3
115         veor            \b2, \b2, \b5
116         veor            \b3, \b3, \b7
117         veor            \b6, \b6, \b1
118         veor            \b2, \b2, \b0
119         veor            \b5, \b5, \b3
120         veor            \b4, \b4, \b6
121         veor            \b0, \b0, \b6
122         veor            \b1, \b1, \b4
123         .endm
124
125         .macro          inv_out_bs_ch, b6, b5, b0, b3, b7, b1, b4, b2
126         veor            \b1, \b1, \b5
127         veor            \b2, \b2, \b7
128         veor            \b3, \b3, \b1
129         veor            \b4, \b4, \b5
130         veor            \b7, \b7, \b5
131         veor            \b3, \b3, \b4
132         veor            \b5, \b5, \b0
133         veor            \b3, \b3, \b7
134         veor            \b6, \b6, \b2
135         veor            \b2, \b2, \b1
136         veor            \b6, \b6, \b3
137         veor            \b3, \b3, \b0
138         veor            \b5, \b5, \b6
139         .endm
140
141         .macro          mul_gf4, x0, x1, y0, y1, t0, t1
142         veor            \t0, \y0, \y1
143         vand            \t0, \t0, \x0
144         veor            \x0, \x0, \x1
145         vand            \t1, \x1, \y0
146         vand            \x0, \x0, \y1
147         veor            \x1, \t1, \t0
148         veor            \x0, \x0, \t1
149         .endm
150
151         .macro          mul_gf4_n_gf4, x0, x1, y0, y1, t0, x2, x3, y2, y3, t1
152         veor            \t0, \y0, \y1
153         veor            \t1, \y2, \y3
154         vand            \t0, \t0, \x0
155         vand            \t1, \t1, \x2
156         veor            \x0, \x0, \x1
157         veor            \x2, \x2, \x3
158         vand            \x1, \x1, \y0
159         vand            \x3, \x3, \y2
160         vand            \x0, \x0, \y1
161         vand            \x2, \x2, \y3
162         veor            \x1, \x1, \x0
163         veor            \x2, \x2, \x3
164         veor            \x0, \x0, \t0
165         veor            \x3, \x3, \t1
166         .endm
167
168         .macro          mul_gf16_2, x0, x1, x2, x3, x4, x5, x6, x7, \
169                                     y0, y1, y2, y3, t0, t1, t2, t3
170         veor            \t0, \x0, \x2
171         veor            \t1, \x1, \x3
172         mul_gf4         \x0, \x1, \y0, \y1, \t2, \t3
173         veor            \y0, \y0, \y2
174         veor            \y1, \y1, \y3
175         mul_gf4_n_gf4   \t0, \t1, \y0, \y1, \t3, \x2, \x3, \y2, \y3, \t2
176         veor            \x0, \x0, \t0
177         veor            \x2, \x2, \t0
178         veor            \x1, \x1, \t1
179         veor            \x3, \x3, \t1
180         veor            \t0, \x4, \x6
181         veor            \t1, \x5, \x7
182         mul_gf4_n_gf4   \t0, \t1, \y0, \y1, \t3, \x6, \x7, \y2, \y3, \t2
183         veor            \y0, \y0, \y2
184         veor            \y1, \y1, \y3
185         mul_gf4         \x4, \x5, \y0, \y1, \t2, \t3
186         veor            \x4, \x4, \t0
187         veor            \x6, \x6, \t0
188         veor            \x5, \x5, \t1
189         veor            \x7, \x7, \t1
190         .endm
191
192         .macro          inv_gf256, x0, x1, x2, x3, x4, x5, x6, x7, \
193                                    t0, t1, t2, t3, s0, s1, s2, s3
194         veor            \t3, \x4, \x6
195         veor            \t0, \x5, \x7
196         veor            \t1, \x1, \x3
197         veor            \s1, \x7, \x6
198         veor            \s0, \x0, \x2
199         veor            \s3, \t3, \t0
200         vorr            \t2, \t0, \t1
201         vand            \s2, \t3, \s0
202         vorr            \t3, \t3, \s0
203         veor            \s0, \s0, \t1
204         vand            \t0, \t0, \t1
205         veor            \t1, \x3, \x2
206         vand            \s3, \s3, \s0
207         vand            \s1, \s1, \t1
208         veor            \t1, \x4, \x5
209         veor            \s0, \x1, \x0
210         veor            \t3, \t3, \s1
211         veor            \t2, \t2, \s1
212         vand            \s1, \t1, \s0
213         vorr            \t1, \t1, \s0
214         veor            \t3, \t3, \s3
215         veor            \t0, \t0, \s1
216         veor            \t2, \t2, \s2
217         veor            \t1, \t1, \s3
218         veor            \t0, \t0, \s2
219         vand            \s0, \x7, \x3
220         veor            \t1, \t1, \s2
221         vand            \s1, \x6, \x2
222         vand            \s2, \x5, \x1
223         vorr            \s3, \x4, \x0
224         veor            \t3, \t3, \s0
225         veor            \t1, \t1, \s2
226         veor            \s0, \t0, \s3
227         veor            \t2, \t2, \s1
228         vand            \s2, \t3, \t1
229         veor            \s1, \t2, \s2
230         veor            \s3, \s0, \s2
231         vbsl            \s1, \t1, \s0
232         vmvn            \t0, \s0
233         vbsl            \s0, \s1, \s3
234         vbsl            \t0, \s1, \s3
235         vbsl            \s3, \t3, \t2
236         veor            \t3, \t3, \t2
237         vand            \s2, \s0, \s3
238         veor            \t1, \t1, \t0
239         veor            \s2, \s2, \t3
240         mul_gf16_2      \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \
241                         \s3, \s2, \s1, \t1, \s0, \t0, \t2, \t3
242         .endm
243
244         .macro          sbox, b0, b1, b2, b3, b4, b5, b6, b7, \
245                               t0, t1, t2, t3, s0, s1, s2, s3
246         in_bs_ch        \b0, \b1, \b2, \b3, \b4, \b5, \b6, \b7
247         inv_gf256       \b6, \b5, \b0, \b3, \b7, \b1, \b4, \b2, \
248                         \t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3
249         out_bs_ch       \b7, \b1, \b4, \b2, \b6, \b5, \b0, \b3
250         .endm
251
252         .macro          inv_sbox, b0, b1, b2, b3, b4, b5, b6, b7, \
253                                   t0, t1, t2, t3, s0, s1, s2, s3
254         inv_in_bs_ch    \b0, \b1, \b2, \b3, \b4, \b5, \b6, \b7
255         inv_gf256       \b5, \b1, \b2, \b6, \b3, \b7, \b0, \b4, \
256                         \t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3
257         inv_out_bs_ch   \b3, \b7, \b0, \b4, \b5, \b1, \b2, \b6
258         .endm
259
260         .macro          shift_rows, x0, x1, x2, x3, x4, x5, x6, x7, \
261                                     t0, t1, t2, t3, mask
262         vld1.8          {\t0-\t1}, [bskey, :256]!
263         veor            \t0, \t0, \x0
264         vld1.8          {\t2-\t3}, [bskey, :256]!
265         veor            \t1, \t1, \x1
266         __tbl           \x0, \t0, \mask
267         veor            \t2, \t2, \x2
268         __tbl           \x1, \t1, \mask
269         vld1.8          {\t0-\t1}, [bskey, :256]!
270         veor            \t3, \t3, \x3
271         __tbl           \x2, \t2, \mask
272         __tbl           \x3, \t3, \mask
273         vld1.8          {\t2-\t3}, [bskey, :256]!
274         veor            \t0, \t0, \x4
275         veor            \t1, \t1, \x5
276         __tbl           \x4, \t0, \mask
277         veor            \t2, \t2, \x6
278         __tbl           \x5, \t1, \mask
279         veor            \t3, \t3, \x7
280         __tbl           \x6, \t2, \mask
281         __tbl           \x7, \t3, \mask
282         .endm
283
284         .macro          inv_shift_rows, x0, x1, x2, x3, x4, x5, x6, x7, \
285                                         t0, t1, t2, t3, mask
286         __tbl           \x0, \x0, \mask, \t0
287         __tbl           \x1, \x1, \mask, \t1
288         __tbl           \x2, \x2, \mask, \t2
289         __tbl           \x3, \x3, \mask, \t3
290         __tbl           \x4, \x4, \mask, \t0
291         __tbl           \x5, \x5, \mask, \t1
292         __tbl           \x6, \x6, \mask, \t2
293         __tbl           \x7, \x7, \mask, \t3
294         .endm
295
296         .macro          mix_cols, x0, x1, x2, x3, x4, x5, x6, x7, \
297                                   t0, t1, t2, t3, t4, t5, t6, t7, inv
298         vext.8          \t0, \x0, \x0, #12
299         vext.8          \t1, \x1, \x1, #12
300         veor            \x0, \x0, \t0
301         vext.8          \t2, \x2, \x2, #12
302         veor            \x1, \x1, \t1
303         vext.8          \t3, \x3, \x3, #12
304         veor            \x2, \x2, \t2
305         vext.8          \t4, \x4, \x4, #12
306         veor            \x3, \x3, \t3
307         vext.8          \t5, \x5, \x5, #12
308         veor            \x4, \x4, \t4
309         vext.8          \t6, \x6, \x6, #12
310         veor            \x5, \x5, \t5
311         vext.8          \t7, \x7, \x7, #12
312         veor            \x6, \x6, \t6
313         veor            \t1, \t1, \x0
314         veor.8          \x7, \x7, \t7
315         vext.8          \x0, \x0, \x0, #8
316         veor            \t2, \t2, \x1
317         veor            \t0, \t0, \x7
318         veor            \t1, \t1, \x7
319         vext.8          \x1, \x1, \x1, #8
320         veor            \t5, \t5, \x4
321         veor            \x0, \x0, \t0
322         veor            \t6, \t6, \x5
323         veor            \x1, \x1, \t1
324         vext.8          \t0, \x4, \x4, #8
325         veor            \t4, \t4, \x3
326         vext.8          \t1, \x5, \x5, #8
327         veor            \t7, \t7, \x6
328         vext.8          \x4, \x3, \x3, #8
329         veor            \t3, \t3, \x2
330         vext.8          \x5, \x7, \x7, #8
331         veor            \t4, \t4, \x7
332         vext.8          \x3, \x6, \x6, #8
333         veor            \t3, \t3, \x7
334         vext.8          \x6, \x2, \x2, #8
335         veor            \x7, \t1, \t5
336         .ifb            \inv
337         veor            \x2, \t0, \t4
338         veor            \x4, \x4, \t3
339         veor            \x5, \x5, \t7
340         veor            \x3, \x3, \t6
341         veor            \x6, \x6, \t2
342         .else
343         veor            \t3, \t3, \x4
344         veor            \x5, \x5, \t7
345         veor            \x2, \x3, \t6
346         veor            \x3, \t0, \t4
347         veor            \x4, \x6, \t2
348         vmov            \x6, \t3
349         .endif
350         .endm
351
352         .macro          inv_mix_cols, x0, x1, x2, x3, x4, x5, x6, x7, \
353                                       t0, t1, t2, t3, t4, t5, t6, t7
354         vld1.8          {\t0-\t1}, [bskey, :256]!
355         veor            \x0, \x0, \t0
356         vld1.8          {\t2-\t3}, [bskey, :256]!
357         veor            \x1, \x1, \t1
358         vld1.8          {\t4-\t5}, [bskey, :256]!
359         veor            \x2, \x2, \t2
360         vld1.8          {\t6-\t7}, [bskey, :256]
361         sub             bskey, bskey, #224
362         veor            \x3, \x3, \t3
363         veor            \x4, \x4, \t4
364         veor            \x5, \x5, \t5
365         veor            \x6, \x6, \t6
366         veor            \x7, \x7, \t7
367         vext.8          \t0, \x0, \x0, #8
368         vext.8          \t6, \x6, \x6, #8
369         vext.8          \t7, \x7, \x7, #8
370         veor            \t0, \t0, \x0
371         vext.8          \t1, \x1, \x1, #8
372         veor            \t6, \t6, \x6
373         vext.8          \t2, \x2, \x2, #8
374         veor            \t7, \t7, \x7
375         vext.8          \t3, \x3, \x3, #8
376         veor            \t1, \t1, \x1
377         vext.8          \t4, \x4, \x4, #8
378         veor            \t2, \t2, \x2
379         vext.8          \t5, \x5, \x5, #8
380         veor            \t3, \t3, \x3
381         veor            \t4, \t4, \x4
382         veor            \t5, \t5, \x5
383         veor            \x0, \x0, \t6
384         veor            \x1, \x1, \t6
385         veor            \x2, \x2, \t0
386         veor            \x4, \x4, \t2
387         veor            \x3, \x3, \t1
388         veor            \x1, \x1, \t7
389         veor            \x2, \x2, \t7
390         veor            \x4, \x4, \t6
391         veor            \x5, \x5, \t3
392         veor            \x3, \x3, \t6
393         veor            \x6, \x6, \t4
394         veor            \x4, \x4, \t7
395         veor            \x5, \x5, \t7
396         veor            \x7, \x7, \t5
397         mix_cols        \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \
398                         \t0, \t1, \t2, \t3, \t4, \t5, \t6, \t7, 1
399         .endm
400
401         .macro          swapmove_2x, a0, b0, a1, b1, n, mask, t0, t1
402         vshr.u64        \t0, \b0, #\n
403         vshr.u64        \t1, \b1, #\n
404         veor            \t0, \t0, \a0
405         veor            \t1, \t1, \a1
406         vand            \t0, \t0, \mask
407         vand            \t1, \t1, \mask
408         veor            \a0, \a0, \t0
409         vshl.s64        \t0, \t0, #\n
410         veor            \a1, \a1, \t1
411         vshl.s64        \t1, \t1, #\n
412         veor            \b0, \b0, \t0
413         veor            \b1, \b1, \t1
414         .endm
415
416         .macro          bitslice, x7, x6, x5, x4, x3, x2, x1, x0, t0, t1, t2, t3
417         vmov.i8         \t0, #0x55
418         vmov.i8         \t1, #0x33
419         swapmove_2x     \x0, \x1, \x2, \x3, 1, \t0, \t2, \t3
420         swapmove_2x     \x4, \x5, \x6, \x7, 1, \t0, \t2, \t3
421         vmov.i8         \t0, #0x0f
422         swapmove_2x     \x0, \x2, \x1, \x3, 2, \t1, \t2, \t3
423         swapmove_2x     \x4, \x6, \x5, \x7, 2, \t1, \t2, \t3
424         swapmove_2x     \x0, \x4, \x1, \x5, 4, \t0, \t2, \t3
425         swapmove_2x     \x2, \x6, \x3, \x7, 4, \t0, \t2, \t3
426         .endm
427
428         .align          4
429 M0:     .quad           0x02060a0e03070b0f, 0x0004080c0105090d
430
431         /*
432          * void aesbs_convert_key(u8 out[], u32 const rk[], int rounds)
433          */
434 ENTRY(aesbs_convert_key)
435         vld1.32         {q7}, [r1]!             // load round 0 key
436         vld1.32         {q15}, [r1]!            // load round 1 key
437
438         vmov.i8         q8,  #0x01              // bit masks
439         vmov.i8         q9,  #0x02
440         vmov.i8         q10, #0x04
441         vmov.i8         q11, #0x08
442         vmov.i8         q12, #0x10
443         vmov.i8         q13, #0x20
444         __ldr           q14, M0
445
446         sub             r2, r2, #1
447         vst1.8          {q7}, [r0, :128]!       // save round 0 key
448
449 .Lkey_loop:
450         __tbl           q7, q15, q14
451         vmov.i8         q6, #0x40
452         vmov.i8         q15, #0x80
453
454         vtst.8          q0, q7, q8
455         vtst.8          q1, q7, q9
456         vtst.8          q2, q7, q10
457         vtst.8          q3, q7, q11
458         vtst.8          q4, q7, q12
459         vtst.8          q5, q7, q13
460         vtst.8          q6, q7, q6
461         vtst.8          q7, q7, q15
462         vld1.32         {q15}, [r1]!            // load next round key
463         vmvn            q0, q0
464         vmvn            q1, q1
465         vmvn            q5, q5
466         vmvn            q6, q6
467
468         subs            r2, r2, #1
469         vst1.8          {q0-q1}, [r0, :256]!
470         vst1.8          {q2-q3}, [r0, :256]!
471         vst1.8          {q4-q5}, [r0, :256]!
472         vst1.8          {q6-q7}, [r0, :256]!
473         bne             .Lkey_loop
474
475         vmov.i8         q7, #0x63               // compose .L63
476         veor            q15, q15, q7
477         vst1.8          {q15}, [r0, :128]
478         bx              lr
479 ENDPROC(aesbs_convert_key)
480
481         .align          4
482 M0SR:   .quad           0x0a0e02060f03070b, 0x0004080c05090d01
483
484 aesbs_encrypt8:
485         vld1.8          {q9}, [bskey, :128]!    // round 0 key
486         __ldr           q8, M0SR
487
488         veor            q10, q0, q9             // xor with round0 key
489         veor            q11, q1, q9
490         __tbl           q0, q10, q8
491         veor            q12, q2, q9
492         __tbl           q1, q11, q8
493         veor            q13, q3, q9
494         __tbl           q2, q12, q8
495         veor            q14, q4, q9
496         __tbl           q3, q13, q8
497         veor            q15, q5, q9
498         __tbl           q4, q14, q8
499         veor            q10, q6, q9
500         __tbl           q5, q15, q8
501         veor            q11, q7, q9
502         __tbl           q6, q10, q8
503         __tbl           q7, q11, q8
504
505         bitslice        q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11
506
507         sub             rounds, rounds, #1
508         b               .Lenc_sbox
509
510         .align          5
511 SR:     .quad           0x0504070600030201, 0x0f0e0d0c0a09080b
512 SRM0:   .quad           0x0304090e00050a0f, 0x01060b0c0207080d
513
514 .Lenc_last:
515         __ldr           q12, SRM0
516 .Lenc_loop:
517         shift_rows      q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12
518 .Lenc_sbox:
519         sbox            q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12, \
520                                                                 q13, q14, q15
521         subs            rounds, rounds, #1
522         bcc             .Lenc_done
523
524         mix_cols        q0, q1, q4, q6, q3, q7, q2, q5, q8, q9, q10, q11, q12, \
525                                                                 q13, q14, q15
526
527         beq             .Lenc_last
528         __ldr           q12, SR
529         b               .Lenc_loop
530
531 .Lenc_done:
532         vld1.8          {q12}, [bskey, :128]    // last round key
533
534         bitslice        q0, q1, q4, q6, q3, q7, q2, q5, q8, q9, q10, q11
535
536         veor            q0, q0, q12
537         veor            q1, q1, q12
538         veor            q4, q4, q12
539         veor            q6, q6, q12
540         veor            q3, q3, q12
541         veor            q7, q7, q12
542         veor            q2, q2, q12
543         veor            q5, q5, q12
544         bx              lr
545 ENDPROC(aesbs_encrypt8)
546
547         .align          4
548 M0ISR:  .quad           0x0a0e0206070b0f03, 0x0004080c0d010509
549
550 aesbs_decrypt8:
551         add             bskey, bskey, rounds, lsl #7
552         sub             bskey, bskey, #112
553         vld1.8          {q9}, [bskey, :128]     // round 0 key
554         sub             bskey, bskey, #128
555         __ldr           q8, M0ISR
556
557         veor            q10, q0, q9             // xor with round0 key
558         veor            q11, q1, q9
559         __tbl           q0, q10, q8
560         veor            q12, q2, q9
561         __tbl           q1, q11, q8
562         veor            q13, q3, q9
563         __tbl           q2, q12, q8
564         veor            q14, q4, q9
565         __tbl           q3, q13, q8
566         veor            q15, q5, q9
567         __tbl           q4, q14, q8
568         veor            q10, q6, q9
569         __tbl           q5, q15, q8
570         veor            q11, q7, q9
571         __tbl           q6, q10, q8
572         __tbl           q7, q11, q8
573
574         bitslice        q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11
575
576         sub             rounds, rounds, #1
577         b               .Ldec_sbox
578
579         .align          5
580 ISR:    .quad           0x0504070602010003, 0x0f0e0d0c080b0a09
581 ISRM0:  .quad           0x01040b0e0205080f, 0x0306090c00070a0d
582
583 .Ldec_last:
584         __ldr           q12, ISRM0
585 .Ldec_loop:
586         inv_shift_rows  q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12
587 .Ldec_sbox:
588         inv_sbox        q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12, \
589                                                                 q13, q14, q15
590         subs            rounds, rounds, #1
591         bcc             .Ldec_done
592
593         inv_mix_cols    q0, q1, q6, q4, q2, q7, q3, q5, q8, q9, q10, q11, q12, \
594                                                                 q13, q14, q15
595
596         beq             .Ldec_last
597         __ldr           q12, ISR
598         b               .Ldec_loop
599
600 .Ldec_done:
601         add             bskey, bskey, #112
602         vld1.8          {q12}, [bskey, :128]    // last round key
603
604         bitslice        q0, q1, q6, q4, q2, q7, q3, q5, q8, q9, q10, q11
605
606         veor            q0, q0, q12
607         veor            q1, q1, q12
608         veor            q6, q6, q12
609         veor            q4, q4, q12
610         veor            q2, q2, q12
611         veor            q7, q7, q12
612         veor            q3, q3, q12
613         veor            q5, q5, q12
614         bx              lr
615 ENDPROC(aesbs_decrypt8)
616
617         /*
618          * aesbs_ecb_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
619          *                   int blocks)
620          * aesbs_ecb_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
621          *                   int blocks)
622          */
623         .macro          __ecb_crypt, do8, o0, o1, o2, o3, o4, o5, o6, o7
624         push            {r4-r6, lr}
625         ldr             r5, [sp, #16]           // number of blocks
626
627 99:     adr             ip, 0f
628         and             lr, r5, #7
629         cmp             r5, #8
630         sub             ip, ip, lr, lsl #2
631         movlt           pc, ip                  // computed goto if blocks < 8
632
633         vld1.8          {q0}, [r1]!
634         vld1.8          {q1}, [r1]!
635         vld1.8          {q2}, [r1]!
636         vld1.8          {q3}, [r1]!
637         vld1.8          {q4}, [r1]!
638         vld1.8          {q5}, [r1]!
639         vld1.8          {q6}, [r1]!
640         vld1.8          {q7}, [r1]!
641
642 0:      mov             bskey, r2
643         mov             rounds, r3
644         bl              \do8
645
646         adr             ip, 1f
647         and             lr, r5, #7
648         cmp             r5, #8
649         sub             ip, ip, lr, lsl #2
650         movlt           pc, ip                  // computed goto if blocks < 8
651
652         vst1.8          {\o0}, [r0]!
653         vst1.8          {\o1}, [r0]!
654         vst1.8          {\o2}, [r0]!
655         vst1.8          {\o3}, [r0]!
656         vst1.8          {\o4}, [r0]!
657         vst1.8          {\o5}, [r0]!
658         vst1.8          {\o6}, [r0]!
659         vst1.8          {\o7}, [r0]!
660
661 1:      subs            r5, r5, #8
662         bgt             99b
663
664         pop             {r4-r6, pc}
665         .endm
666
667         .align          4
668 ENTRY(aesbs_ecb_encrypt)
669         __ecb_crypt     aesbs_encrypt8, q0, q1, q4, q6, q3, q7, q2, q5
670 ENDPROC(aesbs_ecb_encrypt)
671
672         .align          4
673 ENTRY(aesbs_ecb_decrypt)
674         __ecb_crypt     aesbs_decrypt8, q0, q1, q6, q4, q2, q7, q3, q5
675 ENDPROC(aesbs_ecb_decrypt)
676
677         /*
678          * aesbs_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[],
679          *                   int rounds, int blocks, u8 iv[])
680          */
681         .align          4
682 ENTRY(aesbs_cbc_decrypt)
683         mov             ip, sp
684         push            {r4-r6, lr}
685         ldm             ip, {r5-r6}             // load args 4-5
686
687 99:     adr             ip, 0f
688         and             lr, r5, #7
689         cmp             r5, #8
690         sub             ip, ip, lr, lsl #2
691         mov             lr, r1
692         movlt           pc, ip                  // computed goto if blocks < 8
693
694         vld1.8          {q0}, [lr]!
695         vld1.8          {q1}, [lr]!
696         vld1.8          {q2}, [lr]!
697         vld1.8          {q3}, [lr]!
698         vld1.8          {q4}, [lr]!
699         vld1.8          {q5}, [lr]!
700         vld1.8          {q6}, [lr]!
701         vld1.8          {q7}, [lr]
702
703 0:      mov             bskey, r2
704         mov             rounds, r3
705         bl              aesbs_decrypt8
706
707         vld1.8          {q8}, [r6]
708         vmov            q9, q8
709         vmov            q10, q8
710         vmov            q11, q8
711         vmov            q12, q8
712         vmov            q13, q8
713         vmov            q14, q8
714         vmov            q15, q8
715
716         adr             ip, 1f
717         and             lr, r5, #7
718         cmp             r5, #8
719         sub             ip, ip, lr, lsl #2
720         movlt           pc, ip                  // computed goto if blocks < 8
721
722         vld1.8          {q9}, [r1]!
723         vld1.8          {q10}, [r1]!
724         vld1.8          {q11}, [r1]!
725         vld1.8          {q12}, [r1]!
726         vld1.8          {q13}, [r1]!
727         vld1.8          {q14}, [r1]!
728         vld1.8          {q15}, [r1]!
729         W(nop)
730
731 1:      adr             ip, 2f
732         sub             ip, ip, lr, lsl #3
733         movlt           pc, ip                  // computed goto if blocks < 8
734
735         veor            q0, q0, q8
736         vst1.8          {q0}, [r0]!
737         veor            q1, q1, q9
738         vst1.8          {q1}, [r0]!
739         veor            q6, q6, q10
740         vst1.8          {q6}, [r0]!
741         veor            q4, q4, q11
742         vst1.8          {q4}, [r0]!
743         veor            q2, q2, q12
744         vst1.8          {q2}, [r0]!
745         veor            q7, q7, q13
746         vst1.8          {q7}, [r0]!
747         veor            q3, q3, q14
748         vst1.8          {q3}, [r0]!
749         veor            q5, q5, q15
750         vld1.8          {q8}, [r1]!             // load next round's iv
751 2:      vst1.8          {q5}, [r0]!
752
753         subs            r5, r5, #8
754         vst1.8          {q8}, [r6]              // store next round's iv
755         bgt             99b
756
757         pop             {r4-r6, pc}
758 ENDPROC(aesbs_cbc_decrypt)
759
760         .macro          next_ctr, q
761         vmov            \q\()h, r9, r10
762         adds            r10, r10, #1
763         adcs            r9, r9, #0
764         vmov            \q\()l, r7, r8
765         adcs            r8, r8, #0
766         adc             r7, r7, #0
767         vrev32.8        \q, \q
768         .endm
769
770         /*
771          * aesbs_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[],
772          *                   int rounds, int bytes, u8 ctr[])
773          */
774 ENTRY(aesbs_ctr_encrypt)
775         mov             ip, sp
776         push            {r4-r10, lr}
777
778         ldm             ip, {r5, r6}            // load args 4-5
779         vld1.8          {q0}, [r6]              // load counter
780         vrev32.8        q1, q0
781         vmov            r9, r10, d3
782         vmov            r7, r8, d2
783
784         adds            r10, r10, #1
785         adcs            r9, r9, #0
786         adcs            r8, r8, #0
787         adc             r7, r7, #0
788
789 99:     vmov            q1, q0
790         sub             lr, r5, #1
791         vmov            q2, q0
792         adr             ip, 0f
793         vmov            q3, q0
794         and             lr, lr, #112
795         vmov            q4, q0
796         cmp             r5, #112
797         vmov            q5, q0
798         sub             ip, ip, lr, lsl #1
799         vmov            q6, q0
800         add             ip, ip, lr, lsr #2
801         vmov            q7, q0
802         movle           pc, ip                  // computed goto if bytes < 112
803
804         next_ctr        q1
805         next_ctr        q2
806         next_ctr        q3
807         next_ctr        q4
808         next_ctr        q5
809         next_ctr        q6
810         next_ctr        q7
811
812 0:      mov             bskey, r2
813         mov             rounds, r3
814         bl              aesbs_encrypt8
815
816         adr             ip, 1f
817         sub             lr, r5, #1
818         cmp             r5, #128
819         bic             lr, lr, #15
820         ands            r4, r5, #15             // preserves C flag
821         teqcs           r5, r5                  // set Z flag if not last iteration
822         sub             ip, ip, lr, lsr #2
823         rsb             r4, r4, #16
824         movcc           pc, ip                  // computed goto if bytes < 128
825
826         vld1.8          {q8}, [r1]!
827         vld1.8          {q9}, [r1]!
828         vld1.8          {q10}, [r1]!
829         vld1.8          {q11}, [r1]!
830         vld1.8          {q12}, [r1]!
831         vld1.8          {q13}, [r1]!
832         vld1.8          {q14}, [r1]!
833 1:      subne           r1, r1, r4
834         vld1.8          {q15}, [r1]!
835
836         add             ip, ip, #2f - 1b
837
838         veor            q0, q0, q8
839         veor            q1, q1, q9
840         veor            q4, q4, q10
841         veor            q6, q6, q11
842         veor            q3, q3, q12
843         veor            q7, q7, q13
844         veor            q2, q2, q14
845         bne             3f
846         veor            q5, q5, q15
847
848         movcc           pc, ip                  // computed goto if bytes < 128
849
850         vst1.8          {q0}, [r0]!
851         vst1.8          {q1}, [r0]!
852         vst1.8          {q4}, [r0]!
853         vst1.8          {q6}, [r0]!
854         vst1.8          {q3}, [r0]!
855         vst1.8          {q7}, [r0]!
856         vst1.8          {q2}, [r0]!
857 2:      subne           r0, r0, r4
858         vst1.8          {q5}, [r0]!
859
860         next_ctr        q0
861
862         subs            r5, r5, #128
863         bgt             99b
864
865         vst1.8          {q0}, [r6]
866         pop             {r4-r10, pc}
867
868 3:      adr             lr, .Lpermute_table + 16
869         cmp             r5, #16                 // Z flag remains cleared
870         sub             lr, lr, r4
871         vld1.8          {q8-q9}, [lr]
872         vtbl.8          d16, {q5}, d16
873         vtbl.8          d17, {q5}, d17
874         veor            q5, q8, q15
875         bcc             4f                      // have to reload prev if R5 < 16
876         vtbx.8          d10, {q2}, d18
877         vtbx.8          d11, {q2}, d19
878         mov             pc, ip                  // branch back to VST sequence
879
880 4:      sub             r0, r0, r4
881         vshr.s8         q9, q9, #7              // create mask for VBIF
882         vld1.8          {q8}, [r0]              // reload
883         vbif            q5, q8, q9
884         vst1.8          {q5}, [r0]
885         pop             {r4-r10, pc}
886 ENDPROC(aesbs_ctr_encrypt)
887
888         .align          6
889 .Lpermute_table:
890         .byte           0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
891         .byte           0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
892         .byte           0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
893         .byte           0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
894         .byte           0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
895         .byte           0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
896
897         .macro          next_tweak, out, in, const, tmp
898         vshr.s64        \tmp, \in, #63
899         vand            \tmp, \tmp, \const
900         vadd.u64        \out, \in, \in
901         vext.8          \tmp, \tmp, \tmp, #8
902         veor            \out, \out, \tmp
903         .endm
904
905         /*
906          * aesbs_xts_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
907          *                   int blocks, u8 iv[], int reorder_last_tweak)
908          * aesbs_xts_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
909          *                   int blocks, u8 iv[], int reorder_last_tweak)
910          */
911         .align          6
912 __xts_prepare8:
913         vld1.8          {q14}, [r7]             // load iv
914         vmov.i32        d30, #0x87              // compose tweak mask vector
915         vmovl.u32       q15, d30
916         vshr.u64        d30, d31, #7
917         vmov            q12, q14
918
919         adr             ip, 0f
920         and             r4, r6, #7
921         cmp             r6, #8
922         sub             ip, ip, r4, lsl #5
923         mov             r4, sp
924         movlt           pc, ip                  // computed goto if blocks < 8
925
926         vld1.8          {q0}, [r1]!
927         next_tweak      q12, q14, q15, q13
928         veor            q0, q0, q14
929         vst1.8          {q14}, [r4, :128]!
930
931         vld1.8          {q1}, [r1]!
932         next_tweak      q14, q12, q15, q13
933         veor            q1, q1, q12
934         vst1.8          {q12}, [r4, :128]!
935
936         vld1.8          {q2}, [r1]!
937         next_tweak      q12, q14, q15, q13
938         veor            q2, q2, q14
939         vst1.8          {q14}, [r4, :128]!
940
941         vld1.8          {q3}, [r1]!
942         next_tweak      q14, q12, q15, q13
943         veor            q3, q3, q12
944         vst1.8          {q12}, [r4, :128]!
945
946         vld1.8          {q4}, [r1]!
947         next_tweak      q12, q14, q15, q13
948         veor            q4, q4, q14
949         vst1.8          {q14}, [r4, :128]!
950
951         vld1.8          {q5}, [r1]!
952         next_tweak      q14, q12, q15, q13
953         veor            q5, q5, q12
954         vst1.8          {q12}, [r4, :128]!
955
956         vld1.8          {q6}, [r1]!
957         next_tweak      q12, q14, q15, q13
958         veor            q6, q6, q14
959         vst1.8          {q14}, [r4, :128]!
960
961         vld1.8          {q7}, [r1]!
962         next_tweak      q14, q12, q15, q13
963 THUMB(  itt             le              )
964         W(cmple)        r8, #0
965         ble             1f
966 0:      veor            q7, q7, q12
967         vst1.8          {q12}, [r4, :128]
968
969         vst1.8          {q14}, [r7]             // store next iv
970         bx              lr
971
972 1:      vswp            q12, q14
973         b               0b
974 ENDPROC(__xts_prepare8)
975
976         .macro          __xts_crypt, do8, o0, o1, o2, o3, o4, o5, o6, o7
977         push            {r4-r8, lr}
978         mov             r5, sp                  // preserve sp
979         ldrd            r6, r7, [sp, #24]       // get blocks and iv args
980         rsb             r8, ip, #1
981         sub             ip, sp, #128            // make room for 8x tweak
982         bic             ip, ip, #0xf            // align sp to 16 bytes
983         mov             sp, ip
984
985 99:     bl              __xts_prepare8
986
987         mov             bskey, r2
988         mov             rounds, r3
989         bl              \do8
990
991         adr             ip, 0f
992         and             lr, r6, #7
993         cmp             r6, #8
994         sub             ip, ip, lr, lsl #2
995         mov             r4, sp
996         movlt           pc, ip                  // computed goto if blocks < 8
997
998         vld1.8          {q8}, [r4, :128]!
999         vld1.8          {q9}, [r4, :128]!
1000         vld1.8          {q10}, [r4, :128]!
1001         vld1.8          {q11}, [r4, :128]!
1002         vld1.8          {q12}, [r4, :128]!
1003         vld1.8          {q13}, [r4, :128]!
1004         vld1.8          {q14}, [r4, :128]!
1005         vld1.8          {q15}, [r4, :128]
1006
1007 0:      adr             ip, 1f
1008         sub             ip, ip, lr, lsl #3
1009         movlt           pc, ip                  // computed goto if blocks < 8
1010
1011         veor            \o0, \o0, q8
1012         vst1.8          {\o0}, [r0]!
1013         veor            \o1, \o1, q9
1014         vst1.8          {\o1}, [r0]!
1015         veor            \o2, \o2, q10
1016         vst1.8          {\o2}, [r0]!
1017         veor            \o3, \o3, q11
1018         vst1.8          {\o3}, [r0]!
1019         veor            \o4, \o4, q12
1020         vst1.8          {\o4}, [r0]!
1021         veor            \o5, \o5, q13
1022         vst1.8          {\o5}, [r0]!
1023         veor            \o6, \o6, q14
1024         vst1.8          {\o6}, [r0]!
1025         veor            \o7, \o7, q15
1026         vst1.8          {\o7}, [r0]!
1027
1028 1:      subs            r6, r6, #8
1029         bgt             99b
1030
1031         mov             sp, r5
1032         pop             {r4-r8, pc}
1033         .endm
1034
1035 ENTRY(aesbs_xts_encrypt)
1036         mov             ip, #0                  // never reorder final tweak
1037         __xts_crypt     aesbs_encrypt8, q0, q1, q4, q6, q3, q7, q2, q5
1038 ENDPROC(aesbs_xts_encrypt)
1039
1040 ENTRY(aesbs_xts_decrypt)
1041         ldr             ip, [sp, #8]            // reorder final tweak?
1042         __xts_crypt     aesbs_decrypt8, q0, q1, q6, q4, q2, q7, q3, q5
1043 ENDPROC(aesbs_xts_decrypt)