aes-armv4.pl, bsaes-armv7.pl: add Linux kernel and Thumb2 support.
[openssl.git] / crypto / aes / asm / aes-armv4.pl
1 #!/usr/bin/env perl
2
3 # ====================================================================
4 # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
5 # project. The module is, however, dual licensed under OpenSSL and
6 # CRYPTOGAMS licenses depending on where you obtain it. For further
7 # details see http://www.openssl.org/~appro/cryptogams/.
8 # ====================================================================
9
10 # AES for ARMv4
11
12 # January 2007.
13 #
14 # Code uses single 1K S-box and is >2 times faster than code generated
15 # by gcc-3.4.1. This is thanks to unique feature of ARMv4 ISA, which
16 # allows to merge logical or arithmetic operation with shift or rotate
17 # in one instruction and emit combined result every cycle. The module
18 # is endian-neutral. The performance is ~42 cycles/byte for 128-bit
19 # key [on single-issue Xscale PXA250 core].
20
21 # May 2007.
22 #
23 # AES_set_[en|de]crypt_key is added.
24
25 # July 2010.
26 #
27 # Rescheduling for dual-issue pipeline resulted in 12% improvement on
28 # Cortex A8 core and ~25 cycles per byte processed with 128-bit key.
29
30 # February 2011.
31 #
32 # Profiler-assisted and platform-specific optimization resulted in 16%
33 # improvement on Cortex A8 core and ~21.5 cycles per byte.
34
35 while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
36 open STDOUT,">$output";
37
38 $s0="r0";
39 $s1="r1";
40 $s2="r2";
41 $s3="r3";
42 $t1="r4";
43 $t2="r5";
44 $t3="r6";
45 $i1="r7";
46 $i2="r8";
47 $i3="r9";
48
49 $tbl="r10";
50 $key="r11";
51 $rounds="r12";
52
53 $code=<<___;
54 #ifndef __KERNEL__
55 # include "arm_arch.h"
56 #else
57 # define __ARM_ARCH__ __LINUX_ARM_ARCH__
58 #endif
59
60 .text
61 #if __ARM_ARCH__<7
62 .code   32
63 #else
64 .syntax unified
65 #endif
66
67 .type   AES_Te,%object
68 .align  5
69 AES_Te:
70 .word   0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d
71 .word   0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554
72 .word   0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d
73 .word   0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a
74 .word   0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87
75 .word   0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b
76 .word   0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea
77 .word   0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b
78 .word   0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a
79 .word   0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f
80 .word   0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108
81 .word   0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f
82 .word   0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e
83 .word   0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5
84 .word   0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d
85 .word   0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f
86 .word   0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e
87 .word   0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb
88 .word   0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce
89 .word   0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497
90 .word   0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c
91 .word   0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed
92 .word   0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b
93 .word   0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a
94 .word   0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16
95 .word   0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594
96 .word   0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81
97 .word   0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3
98 .word   0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a
99 .word   0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504
100 .word   0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163
101 .word   0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d
102 .word   0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f
103 .word   0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739
104 .word   0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47
105 .word   0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395
106 .word   0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f
107 .word   0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883
108 .word   0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c
109 .word   0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76
110 .word   0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e
111 .word   0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4
112 .word   0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6
113 .word   0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b
114 .word   0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7
115 .word   0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0
116 .word   0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25
117 .word   0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818
118 .word   0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72
119 .word   0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651
120 .word   0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21
121 .word   0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85
122 .word   0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa
123 .word   0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12
124 .word   0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0
125 .word   0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9
126 .word   0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133
127 .word   0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7
128 .word   0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920
129 .word   0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a
130 .word   0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17
131 .word   0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8
132 .word   0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11
133 .word   0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a
134 @ Te4[256]
135 .byte   0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
136 .byte   0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
137 .byte   0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
138 .byte   0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
139 .byte   0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
140 .byte   0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
141 .byte   0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
142 .byte   0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
143 .byte   0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
144 .byte   0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
145 .byte   0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
146 .byte   0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
147 .byte   0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
148 .byte   0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
149 .byte   0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
150 .byte   0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
151 .byte   0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
152 .byte   0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
153 .byte   0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
154 .byte   0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
155 .byte   0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
156 .byte   0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
157 .byte   0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
158 .byte   0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
159 .byte   0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
160 .byte   0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
161 .byte   0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
162 .byte   0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
163 .byte   0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
164 .byte   0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
165 .byte   0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
166 .byte   0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
167 @ rcon[]
168 .word   0x01000000, 0x02000000, 0x04000000, 0x08000000
169 .word   0x10000000, 0x20000000, 0x40000000, 0x80000000
170 .word   0x1B000000, 0x36000000, 0, 0, 0, 0, 0, 0
171 .size   AES_Te,.-AES_Te
172
173 @ void AES_encrypt(const unsigned char *in, unsigned char *out,
174 @                const AES_KEY *key) {
175 .global AES_encrypt
176 .type   AES_encrypt,%function
177 .align  5
178 AES_encrypt:
179 #if __ARM_ARCH__<7
180         sub     r3,pc,#8                @ AES_encrypt
181 #else
182         adr     r3,AES_encrypt
183 #endif
184         stmdb   sp!,{r1,r4-r12,lr}
185         mov     $rounds,r0              @ inp
186         mov     $key,r2
187         sub     $tbl,r3,#AES_encrypt-AES_Te     @ Te
188 #if __ARM_ARCH__<7
189         ldrb    $s0,[$rounds,#3]        @ load input data in endian-neutral
190         ldrb    $t1,[$rounds,#2]        @ manner...
191         ldrb    $t2,[$rounds,#1]
192         ldrb    $t3,[$rounds,#0]
193         orr     $s0,$s0,$t1,lsl#8
194         ldrb    $s1,[$rounds,#7]
195         orr     $s0,$s0,$t2,lsl#16
196         ldrb    $t1,[$rounds,#6]
197         orr     $s0,$s0,$t3,lsl#24
198         ldrb    $t2,[$rounds,#5]
199         ldrb    $t3,[$rounds,#4]
200         orr     $s1,$s1,$t1,lsl#8
201         ldrb    $s2,[$rounds,#11]
202         orr     $s1,$s1,$t2,lsl#16
203         ldrb    $t1,[$rounds,#10]
204         orr     $s1,$s1,$t3,lsl#24
205         ldrb    $t2,[$rounds,#9]
206         ldrb    $t3,[$rounds,#8]
207         orr     $s2,$s2,$t1,lsl#8
208         ldrb    $s3,[$rounds,#15]
209         orr     $s2,$s2,$t2,lsl#16
210         ldrb    $t1,[$rounds,#14]
211         orr     $s2,$s2,$t3,lsl#24
212         ldrb    $t2,[$rounds,#13]
213         ldrb    $t3,[$rounds,#12]
214         orr     $s3,$s3,$t1,lsl#8
215         orr     $s3,$s3,$t2,lsl#16
216         orr     $s3,$s3,$t3,lsl#24
217 #else
218         ldr     $s0,[$rounds,#0]
219         ldr     $s1,[$rounds,#4]
220         ldr     $s2,[$rounds,#8]
221         ldr     $s3,[$rounds,#12]
222 #ifdef __ARMEL__
223         rev     $s0,$s0
224         rev     $s1,$s1
225         rev     $s2,$s2
226         rev     $s3,$s3
227 #endif
228 #endif
229         bl      _armv4_AES_encrypt
230
231         ldr     $rounds,[sp],#4         @ pop out
232 #if __ARM_ARCH__>=7
233 #ifdef __ARMEL__
234         rev     $s0,$s0
235         rev     $s1,$s1
236         rev     $s2,$s2
237         rev     $s3,$s3
238 #endif
239         str     $s0,[$rounds,#0]
240         str     $s1,[$rounds,#4]
241         str     $s2,[$rounds,#8]
242         str     $s3,[$rounds,#12]
243 #else
244         mov     $t1,$s0,lsr#24          @ write output in endian-neutral
245         mov     $t2,$s0,lsr#16          @ manner...
246         mov     $t3,$s0,lsr#8
247         strb    $t1,[$rounds,#0]
248         strb    $t2,[$rounds,#1]
249         mov     $t1,$s1,lsr#24
250         strb    $t3,[$rounds,#2]
251         mov     $t2,$s1,lsr#16
252         strb    $s0,[$rounds,#3]
253         mov     $t3,$s1,lsr#8
254         strb    $t1,[$rounds,#4]
255         strb    $t2,[$rounds,#5]
256         mov     $t1,$s2,lsr#24
257         strb    $t3,[$rounds,#6]
258         mov     $t2,$s2,lsr#16
259         strb    $s1,[$rounds,#7]
260         mov     $t3,$s2,lsr#8
261         strb    $t1,[$rounds,#8]
262         strb    $t2,[$rounds,#9]
263         mov     $t1,$s3,lsr#24
264         strb    $t3,[$rounds,#10]
265         mov     $t2,$s3,lsr#16
266         strb    $s2,[$rounds,#11]
267         mov     $t3,$s3,lsr#8
268         strb    $t1,[$rounds,#12]
269         strb    $t2,[$rounds,#13]
270         strb    $t3,[$rounds,#14]
271         strb    $s3,[$rounds,#15]
272 #endif
273 #if __ARM_ARCH__>=5
274         ldmia   sp!,{r4-r12,pc}
275 #else
276         ldmia   sp!,{r4-r12,lr}
277         tst     lr,#1
278         moveq   pc,lr                   @ be binary compatible with V4, yet
279         bx      lr                      @ interoperable with Thumb ISA:-)
280 #endif
281 .size   AES_encrypt,.-AES_encrypt
282
283 .type   _armv4_AES_encrypt,%function
284 .align  2
285 _armv4_AES_encrypt:
286         str     lr,[sp,#-4]!            @ push lr
287         ldmia   $key!,{$t1-$i1}
288         eor     $s0,$s0,$t1
289         ldr     $rounds,[$key,#240-16]
290         eor     $s1,$s1,$t2
291         eor     $s2,$s2,$t3
292         eor     $s3,$s3,$i1
293         sub     $rounds,$rounds,#1
294         mov     lr,#255
295
296         and     $i1,lr,$s0
297         and     $i2,lr,$s0,lsr#8
298         and     $i3,lr,$s0,lsr#16
299         mov     $s0,$s0,lsr#24
300 .Lenc_loop:
301         ldr     $t1,[$tbl,$i1,lsl#2]    @ Te3[s0>>0]
302         and     $i1,lr,$s1,lsr#16       @ i0
303         ldr     $t2,[$tbl,$i2,lsl#2]    @ Te2[s0>>8]
304         and     $i2,lr,$s1
305         ldr     $t3,[$tbl,$i3,lsl#2]    @ Te1[s0>>16]
306         and     $i3,lr,$s1,lsr#8
307         ldr     $s0,[$tbl,$s0,lsl#2]    @ Te0[s0>>24]
308         mov     $s1,$s1,lsr#24
309
310         ldr     $i1,[$tbl,$i1,lsl#2]    @ Te1[s1>>16]
311         ldr     $i2,[$tbl,$i2,lsl#2]    @ Te3[s1>>0]
312         ldr     $i3,[$tbl,$i3,lsl#2]    @ Te2[s1>>8]
313         eor     $s0,$s0,$i1,ror#8
314         ldr     $s1,[$tbl,$s1,lsl#2]    @ Te0[s1>>24]
315         and     $i1,lr,$s2,lsr#8        @ i0
316         eor     $t2,$t2,$i2,ror#8
317         and     $i2,lr,$s2,lsr#16       @ i1
318         eor     $t3,$t3,$i3,ror#8
319         and     $i3,lr,$s2
320         ldr     $i1,[$tbl,$i1,lsl#2]    @ Te2[s2>>8]
321         eor     $s1,$s1,$t1,ror#24
322         ldr     $i2,[$tbl,$i2,lsl#2]    @ Te1[s2>>16]
323         mov     $s2,$s2,lsr#24
324
325         ldr     $i3,[$tbl,$i3,lsl#2]    @ Te3[s2>>0]
326         eor     $s0,$s0,$i1,ror#16
327         ldr     $s2,[$tbl,$s2,lsl#2]    @ Te0[s2>>24]
328         and     $i1,lr,$s3              @ i0
329         eor     $s1,$s1,$i2,ror#8
330         and     $i2,lr,$s3,lsr#8        @ i1
331         eor     $t3,$t3,$i3,ror#16
332         and     $i3,lr,$s3,lsr#16       @ i2
333         ldr     $i1,[$tbl,$i1,lsl#2]    @ Te3[s3>>0]
334         eor     $s2,$s2,$t2,ror#16
335         ldr     $i2,[$tbl,$i2,lsl#2]    @ Te2[s3>>8]
336         mov     $s3,$s3,lsr#24
337
338         ldr     $i3,[$tbl,$i3,lsl#2]    @ Te1[s3>>16]
339         eor     $s0,$s0,$i1,ror#24
340         ldr     $i1,[$key],#16
341         eor     $s1,$s1,$i2,ror#16
342         ldr     $s3,[$tbl,$s3,lsl#2]    @ Te0[s3>>24]
343         eor     $s2,$s2,$i3,ror#8
344         ldr     $t1,[$key,#-12]
345         eor     $s3,$s3,$t3,ror#8
346
347         ldr     $t2,[$key,#-8]
348         eor     $s0,$s0,$i1
349         ldr     $t3,[$key,#-4]
350         and     $i1,lr,$s0
351         eor     $s1,$s1,$t1
352         and     $i2,lr,$s0,lsr#8
353         eor     $s2,$s2,$t2
354         and     $i3,lr,$s0,lsr#16
355         eor     $s3,$s3,$t3
356         mov     $s0,$s0,lsr#24
357
358         subs    $rounds,$rounds,#1
359         bne     .Lenc_loop
360
361         add     $tbl,$tbl,#2
362
363         ldrb    $t1,[$tbl,$i1,lsl#2]    @ Te4[s0>>0]
364         and     $i1,lr,$s1,lsr#16       @ i0
365         ldrb    $t2,[$tbl,$i2,lsl#2]    @ Te4[s0>>8]
366         and     $i2,lr,$s1
367         ldrb    $t3,[$tbl,$i3,lsl#2]    @ Te4[s0>>16]
368         and     $i3,lr,$s1,lsr#8
369         ldrb    $s0,[$tbl,$s0,lsl#2]    @ Te4[s0>>24]
370         mov     $s1,$s1,lsr#24
371
372         ldrb    $i1,[$tbl,$i1,lsl#2]    @ Te4[s1>>16]
373         ldrb    $i2,[$tbl,$i2,lsl#2]    @ Te4[s1>>0]
374         ldrb    $i3,[$tbl,$i3,lsl#2]    @ Te4[s1>>8]
375         eor     $s0,$i1,$s0,lsl#8
376         ldrb    $s1,[$tbl,$s1,lsl#2]    @ Te4[s1>>24]
377         and     $i1,lr,$s2,lsr#8        @ i0
378         eor     $t2,$i2,$t2,lsl#8
379         and     $i2,lr,$s2,lsr#16       @ i1
380         eor     $t3,$i3,$t3,lsl#8
381         and     $i3,lr,$s2
382         ldrb    $i1,[$tbl,$i1,lsl#2]    @ Te4[s2>>8]
383         eor     $s1,$t1,$s1,lsl#24
384         ldrb    $i2,[$tbl,$i2,lsl#2]    @ Te4[s2>>16]
385         mov     $s2,$s2,lsr#24
386
387         ldrb    $i3,[$tbl,$i3,lsl#2]    @ Te4[s2>>0]
388         eor     $s0,$i1,$s0,lsl#8
389         ldrb    $s2,[$tbl,$s2,lsl#2]    @ Te4[s2>>24]
390         and     $i1,lr,$s3              @ i0
391         eor     $s1,$s1,$i2,lsl#16
392         and     $i2,lr,$s3,lsr#8        @ i1
393         eor     $t3,$i3,$t3,lsl#8
394         and     $i3,lr,$s3,lsr#16       @ i2
395         ldrb    $i1,[$tbl,$i1,lsl#2]    @ Te4[s3>>0]
396         eor     $s2,$t2,$s2,lsl#24
397         ldrb    $i2,[$tbl,$i2,lsl#2]    @ Te4[s3>>8]
398         mov     $s3,$s3,lsr#24
399
400         ldrb    $i3,[$tbl,$i3,lsl#2]    @ Te4[s3>>16]
401         eor     $s0,$i1,$s0,lsl#8
402         ldr     $i1,[$key,#0]
403         ldrb    $s3,[$tbl,$s3,lsl#2]    @ Te4[s3>>24]
404         eor     $s1,$s1,$i2,lsl#8
405         ldr     $t1,[$key,#4]
406         eor     $s2,$s2,$i3,lsl#16
407         ldr     $t2,[$key,#8]
408         eor     $s3,$t3,$s3,lsl#24
409         ldr     $t3,[$key,#12]
410
411         eor     $s0,$s0,$i1
412         eor     $s1,$s1,$t1
413         eor     $s2,$s2,$t2
414         eor     $s3,$s3,$t3
415
416         sub     $tbl,$tbl,#2
417         ldr     pc,[sp],#4              @ pop and return
418 .size   _armv4_AES_encrypt,.-_armv4_AES_encrypt
419
420 .global AES_set_encrypt_key
421 .type   AES_set_encrypt_key,%function
422 .align  5
423 AES_set_encrypt_key:
424 _armv4_AES_set_encrypt_key:
425 #if __ARM_ARCH__<7
426         sub     r3,pc,#8                @ AES_set_encrypt_key
427 #else
428         adr     r3,AES_set_encrypt_key
429 #endif
430         teq     r0,#0
431 #if __ARM_ARCH__>=7
432         itt     eq                      @ Thumb2 thing, sanity check in ARM
433 #endif
434         moveq   r0,#-1
435         beq     .Labrt
436         teq     r2,#0
437 #if __ARM_ARCH__>=7
438         itt     eq                      @ Thumb2 thing, sanity check in ARM
439 #endif
440         moveq   r0,#-1
441         beq     .Labrt
442
443         teq     r1,#128
444         beq     .Lok
445         teq     r1,#192
446         beq     .Lok
447         teq     r1,#256
448 #if __ARM_ARCH__>=7
449         itt     ne                      @ Thumb2 thing, sanity check in ARM
450 #endif
451         movne   r0,#-1
452         bne     .Labrt
453
454 .Lok:   stmdb   sp!,{r4-r12,lr}
455         sub     $tbl,r3,#_armv4_AES_set_encrypt_key-AES_Te-1024 @ Te4
456
457         mov     $rounds,r0              @ inp
458         mov     lr,r1                   @ bits
459         mov     $key,r2                 @ key
460
461 #if __ARM_ARCH__<7
462         ldrb    $s0,[$rounds,#3]        @ load input data in endian-neutral
463         ldrb    $t1,[$rounds,#2]        @ manner...
464         ldrb    $t2,[$rounds,#1]
465         ldrb    $t3,[$rounds,#0]
466         orr     $s0,$s0,$t1,lsl#8
467         ldrb    $s1,[$rounds,#7]
468         orr     $s0,$s0,$t2,lsl#16
469         ldrb    $t1,[$rounds,#6]
470         orr     $s0,$s0,$t3,lsl#24
471         ldrb    $t2,[$rounds,#5]
472         ldrb    $t3,[$rounds,#4]
473         orr     $s1,$s1,$t1,lsl#8
474         ldrb    $s2,[$rounds,#11]
475         orr     $s1,$s1,$t2,lsl#16
476         ldrb    $t1,[$rounds,#10]
477         orr     $s1,$s1,$t3,lsl#24
478         ldrb    $t2,[$rounds,#9]
479         ldrb    $t3,[$rounds,#8]
480         orr     $s2,$s2,$t1,lsl#8
481         ldrb    $s3,[$rounds,#15]
482         orr     $s2,$s2,$t2,lsl#16
483         ldrb    $t1,[$rounds,#14]
484         orr     $s2,$s2,$t3,lsl#24
485         ldrb    $t2,[$rounds,#13]
486         ldrb    $t3,[$rounds,#12]
487         orr     $s3,$s3,$t1,lsl#8
488         str     $s0,[$key],#16
489         orr     $s3,$s3,$t2,lsl#16
490         str     $s1,[$key,#-12]
491         orr     $s3,$s3,$t3,lsl#24
492         str     $s2,[$key,#-8]
493         str     $s3,[$key,#-4]
494 #else
495         ldr     $s0,[$rounds,#0]
496         ldr     $s1,[$rounds,#4]
497         ldr     $s2,[$rounds,#8]
498         ldr     $s3,[$rounds,#12]
499 #ifdef __ARMEL__
500         rev     $s0,$s0
501         rev     $s1,$s1
502         rev     $s2,$s2
503         rev     $s3,$s3
504 #endif
505         str     $s0,[$key],#16
506         str     $s1,[$key,#-12]
507         str     $s2,[$key,#-8]
508         str     $s3,[$key,#-4]
509 #endif
510
511         teq     lr,#128
512         bne     .Lnot128
513         mov     $rounds,#10
514         str     $rounds,[$key,#240-16]
515         add     $t3,$tbl,#256                   @ rcon
516         mov     lr,#255
517
518 .L128_loop:
519         and     $t2,lr,$s3,lsr#24
520         and     $i1,lr,$s3,lsr#16
521         ldrb    $t2,[$tbl,$t2]
522         and     $i2,lr,$s3,lsr#8
523         ldrb    $i1,[$tbl,$i1]
524         and     $i3,lr,$s3
525         ldrb    $i2,[$tbl,$i2]
526         orr     $t2,$t2,$i1,lsl#24
527         ldrb    $i3,[$tbl,$i3]
528         orr     $t2,$t2,$i2,lsl#16
529         ldr     $t1,[$t3],#4                    @ rcon[i++]
530         orr     $t2,$t2,$i3,lsl#8
531         eor     $t2,$t2,$t1
532         eor     $s0,$s0,$t2                     @ rk[4]=rk[0]^...
533         eor     $s1,$s1,$s0                     @ rk[5]=rk[1]^rk[4]
534         str     $s0,[$key],#16
535         eor     $s2,$s2,$s1                     @ rk[6]=rk[2]^rk[5]
536         str     $s1,[$key,#-12]
537         eor     $s3,$s3,$s2                     @ rk[7]=rk[3]^rk[6]
538         str     $s2,[$key,#-8]
539         subs    $rounds,$rounds,#1
540         str     $s3,[$key,#-4]
541         bne     .L128_loop
542         sub     r2,$key,#176
543         b       .Ldone
544
545 .Lnot128:
546 #if __ARM_ARCH__<7
547         ldrb    $i2,[$rounds,#19]
548         ldrb    $t1,[$rounds,#18]
549         ldrb    $t2,[$rounds,#17]
550         ldrb    $t3,[$rounds,#16]
551         orr     $i2,$i2,$t1,lsl#8
552         ldrb    $i3,[$rounds,#23]
553         orr     $i2,$i2,$t2,lsl#16
554         ldrb    $t1,[$rounds,#22]
555         orr     $i2,$i2,$t3,lsl#24
556         ldrb    $t2,[$rounds,#21]
557         ldrb    $t3,[$rounds,#20]
558         orr     $i3,$i3,$t1,lsl#8
559         orr     $i3,$i3,$t2,lsl#16
560         str     $i2,[$key],#8
561         orr     $i3,$i3,$t3,lsl#24
562         str     $i3,[$key,#-4]
563 #else
564         ldr     $i2,[$rounds,#16]
565         ldr     $i3,[$rounds,#20]
566 #ifdef __ARMEL__
567         rev     $i2,$i2
568         rev     $i3,$i3
569 #endif
570         str     $i2,[$key],#8
571         str     $i3,[$key,#-4]
572 #endif
573
574         teq     lr,#192
575         bne     .Lnot192
576         mov     $rounds,#12
577         str     $rounds,[$key,#240-24]
578         add     $t3,$tbl,#256                   @ rcon
579         mov     lr,#255
580         mov     $rounds,#8
581
582 .L192_loop:
583         and     $t2,lr,$i3,lsr#24
584         and     $i1,lr,$i3,lsr#16
585         ldrb    $t2,[$tbl,$t2]
586         and     $i2,lr,$i3,lsr#8
587         ldrb    $i1,[$tbl,$i1]
588         and     $i3,lr,$i3
589         ldrb    $i2,[$tbl,$i2]
590         orr     $t2,$t2,$i1,lsl#24
591         ldrb    $i3,[$tbl,$i3]
592         orr     $t2,$t2,$i2,lsl#16
593         ldr     $t1,[$t3],#4                    @ rcon[i++]
594         orr     $t2,$t2,$i3,lsl#8
595         eor     $i3,$t2,$t1
596         eor     $s0,$s0,$i3                     @ rk[6]=rk[0]^...
597         eor     $s1,$s1,$s0                     @ rk[7]=rk[1]^rk[6]
598         str     $s0,[$key],#24
599         eor     $s2,$s2,$s1                     @ rk[8]=rk[2]^rk[7]
600         str     $s1,[$key,#-20]
601         eor     $s3,$s3,$s2                     @ rk[9]=rk[3]^rk[8]
602         str     $s2,[$key,#-16]
603         subs    $rounds,$rounds,#1
604         str     $s3,[$key,#-12]
605 #if __ARM_ARCH__>=7
606         itt     eq                              @ Thumb2 thing, sanity check in ARM
607 #endif
608         subeq   r2,$key,#216
609         beq     .Ldone
610
611         ldr     $i1,[$key,#-32]
612         ldr     $i2,[$key,#-28]
613         eor     $i1,$i1,$s3                     @ rk[10]=rk[4]^rk[9]
614         eor     $i3,$i2,$i1                     @ rk[11]=rk[5]^rk[10]
615         str     $i1,[$key,#-8]
616         str     $i3,[$key,#-4]
617         b       .L192_loop
618
619 .Lnot192:
620 #if __ARM_ARCH__<7
621         ldrb    $i2,[$rounds,#27]
622         ldrb    $t1,[$rounds,#26]
623         ldrb    $t2,[$rounds,#25]
624         ldrb    $t3,[$rounds,#24]
625         orr     $i2,$i2,$t1,lsl#8
626         ldrb    $i3,[$rounds,#31]
627         orr     $i2,$i2,$t2,lsl#16
628         ldrb    $t1,[$rounds,#30]
629         orr     $i2,$i2,$t3,lsl#24
630         ldrb    $t2,[$rounds,#29]
631         ldrb    $t3,[$rounds,#28]
632         orr     $i3,$i3,$t1,lsl#8
633         orr     $i3,$i3,$t2,lsl#16
634         str     $i2,[$key],#8
635         orr     $i3,$i3,$t3,lsl#24
636         str     $i3,[$key,#-4]
637 #else
638         ldr     $i2,[$rounds,#24]
639         ldr     $i3,[$rounds,#28]
640 #ifdef __ARMEL__
641         rev     $i2,$i2
642         rev     $i3,$i3
643 #endif
644         str     $i2,[$key],#8
645         str     $i3,[$key,#-4]
646 #endif
647
648         mov     $rounds,#14
649         str     $rounds,[$key,#240-32]
650         add     $t3,$tbl,#256                   @ rcon
651         mov     lr,#255
652         mov     $rounds,#7
653
654 .L256_loop:
655         and     $t2,lr,$i3,lsr#24
656         and     $i1,lr,$i3,lsr#16
657         ldrb    $t2,[$tbl,$t2]
658         and     $i2,lr,$i3,lsr#8
659         ldrb    $i1,[$tbl,$i1]
660         and     $i3,lr,$i3
661         ldrb    $i2,[$tbl,$i2]
662         orr     $t2,$t2,$i1,lsl#24
663         ldrb    $i3,[$tbl,$i3]
664         orr     $t2,$t2,$i2,lsl#16
665         ldr     $t1,[$t3],#4                    @ rcon[i++]
666         orr     $t2,$t2,$i3,lsl#8
667         eor     $i3,$t2,$t1
668         eor     $s0,$s0,$i3                     @ rk[8]=rk[0]^...
669         eor     $s1,$s1,$s0                     @ rk[9]=rk[1]^rk[8]
670         str     $s0,[$key],#32
671         eor     $s2,$s2,$s1                     @ rk[10]=rk[2]^rk[9]
672         str     $s1,[$key,#-28]
673         eor     $s3,$s3,$s2                     @ rk[11]=rk[3]^rk[10]
674         str     $s2,[$key,#-24]
675         subs    $rounds,$rounds,#1
676         str     $s3,[$key,#-20]
677 #if __ARM_ARCH__>=7
678         itt     eq                              @ Thumb2 thing, sanity check in ARM
679 #endif
680         subeq   r2,$key,#256
681         beq     .Ldone
682
683         and     $t2,lr,$s3
684         and     $i1,lr,$s3,lsr#8
685         ldrb    $t2,[$tbl,$t2]
686         and     $i2,lr,$s3,lsr#16
687         ldrb    $i1,[$tbl,$i1]
688         and     $i3,lr,$s3,lsr#24
689         ldrb    $i2,[$tbl,$i2]
690         orr     $t2,$t2,$i1,lsl#8
691         ldrb    $i3,[$tbl,$i3]
692         orr     $t2,$t2,$i2,lsl#16
693         ldr     $t1,[$key,#-48]
694         orr     $t2,$t2,$i3,lsl#24
695
696         ldr     $i1,[$key,#-44]
697         ldr     $i2,[$key,#-40]
698         eor     $t1,$t1,$t2                     @ rk[12]=rk[4]^...
699         ldr     $i3,[$key,#-36]
700         eor     $i1,$i1,$t1                     @ rk[13]=rk[5]^rk[12]
701         str     $t1,[$key,#-16]
702         eor     $i2,$i2,$i1                     @ rk[14]=rk[6]^rk[13]
703         str     $i1,[$key,#-12]
704         eor     $i3,$i3,$i2                     @ rk[15]=rk[7]^rk[14]
705         str     $i2,[$key,#-8]
706         str     $i3,[$key,#-4]
707         b       .L256_loop
708
709 .align  2
710 .Ldone: mov     r0,#0
711         ldmia   sp!,{r4-r12,lr}
712 .Labrt:
713 #if defined(__thumb2__) && __ARM_ARCH__>=7
714         .short  0x4770                  @ bx lr in Thumb2 encoding
715 #else
716         tst     lr,#1
717         moveq   pc,lr                   @ be binary compatible with V4, yet
718         bx      lr                      @ interoperable with Thumb ISA:-)
719 #endif
720 .size   AES_set_encrypt_key,.-AES_set_encrypt_key
721
722 .global AES_set_decrypt_key
723 .type   AES_set_decrypt_key,%function
724 .align  5
725 AES_set_decrypt_key:
726         str     lr,[sp,#-4]!            @ push lr
727         bl      _armv4_AES_set_encrypt_key
728         teq     r0,#0
729         ldr     lr,[sp],#4              @ pop lr
730         bne     .Labrt
731
732         mov     r0,r2                   @ AES_set_encrypt_key preserves r2,
733         mov     r1,r2                   @ which is AES_KEY *key
734         b       _armv4_AES_set_enc2dec_key
735 .size   AES_set_decrypt_key,.-AES_set_decrypt_key
736
737 @ void AES_set_enc2dec_key(const AES_KEY *inp,AES_KEY *out)
738 .global AES_set_enc2dec_key
739 .type   AES_set_enc2dec_key,%function
740 .align  5
741 AES_set_enc2dec_key:
742 _armv4_AES_set_enc2dec_key:
743         stmdb   sp!,{r4-r12,lr}
744
745         ldr     $rounds,[r0,#240]
746         mov     $i1,r0                  @ input
747         add     $i2,r0,$rounds,lsl#4
748         mov     $key,r1                 @ ouput
749         add     $tbl,r1,$rounds,lsl#4
750         str     $rounds,[r1,#240]
751
752 .Linv:  ldr     $s0,[$i1],#16
753         ldr     $s1,[$i1,#-12]
754         ldr     $s2,[$i1,#-8]
755         ldr     $s3,[$i1,#-4]
756         ldr     $t1,[$i2],#-16
757         ldr     $t2,[$i2,#16+4]
758         ldr     $t3,[$i2,#16+8]
759         ldr     $i3,[$i2,#16+12]
760         str     $s0,[$tbl],#-16
761         str     $s1,[$tbl,#16+4]
762         str     $s2,[$tbl,#16+8]
763         str     $s3,[$tbl,#16+12]
764         str     $t1,[$key],#16
765         str     $t2,[$key,#-12]
766         str     $t3,[$key,#-8]
767         str     $i3,[$key,#-4]
768         teq     $i1,$i2
769         bne     .Linv
770
771         ldr     $s0,[$i1]
772         ldr     $s1,[$i1,#4]
773         ldr     $s2,[$i1,#8]
774         ldr     $s3,[$i1,#12]
775         str     $s0,[$key]
776         str     $s1,[$key,#4]
777         str     $s2,[$key,#8]
778         str     $s3,[$key,#12]
779         sub     $key,$key,$rounds,lsl#3
780 ___
781 $mask80=$i1;
782 $mask1b=$i2;
783 $mask7f=$i3;
784 $code.=<<___;
785         ldr     $s0,[$key,#16]!         @ prefetch tp1
786         mov     $mask80,#0x80
787         mov     $mask1b,#0x1b
788         orr     $mask80,$mask80,#0x8000
789         orr     $mask1b,$mask1b,#0x1b00
790         orr     $mask80,$mask80,$mask80,lsl#16
791         orr     $mask1b,$mask1b,$mask1b,lsl#16
792         sub     $rounds,$rounds,#1
793         mvn     $mask7f,$mask80
794         mov     $rounds,$rounds,lsl#2   @ (rounds-1)*4
795
796 .Lmix:  and     $t1,$s0,$mask80
797         and     $s1,$s0,$mask7f
798         sub     $t1,$t1,$t1,lsr#7
799         and     $t1,$t1,$mask1b
800         eor     $s1,$t1,$s1,lsl#1       @ tp2
801
802         and     $t1,$s1,$mask80
803         and     $s2,$s1,$mask7f
804         sub     $t1,$t1,$t1,lsr#7
805         and     $t1,$t1,$mask1b
806         eor     $s2,$t1,$s2,lsl#1       @ tp4
807
808         and     $t1,$s2,$mask80
809         and     $s3,$s2,$mask7f
810         sub     $t1,$t1,$t1,lsr#7
811         and     $t1,$t1,$mask1b
812         eor     $s3,$t1,$s3,lsl#1       @ tp8
813
814         eor     $t1,$s1,$s2
815         eor     $t2,$s0,$s3             @ tp9
816         eor     $t1,$t1,$s3             @ tpe
817         eor     $t1,$t1,$s1,ror#24
818         eor     $t1,$t1,$t2,ror#24      @ ^= ROTATE(tpb=tp9^tp2,8)
819         eor     $t1,$t1,$s2,ror#16
820         eor     $t1,$t1,$t2,ror#16      @ ^= ROTATE(tpd=tp9^tp4,16)
821         eor     $t1,$t1,$t2,ror#8       @ ^= ROTATE(tp9,24)
822
823         ldr     $s0,[$key,#4]           @ prefetch tp1
824         str     $t1,[$key],#4
825         subs    $rounds,$rounds,#1
826         bne     .Lmix
827
828         mov     r0,#0
829 #if __ARM_ARCH__>=5
830         ldmia   sp!,{r4-r12,pc}
831 #else
832         ldmia   sp!,{r4-r12,lr}
833         tst     lr,#1
834         moveq   pc,lr                   @ be binary compatible with V4, yet
835         bx      lr                      @ interoperable with Thumb ISA:-)
836 #endif
837 .size   AES_set_enc2dec_key,.-AES_set_enc2dec_key
838
839 .type   AES_Td,%object
840 .align  5
841 AES_Td:
842 .word   0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96
843 .word   0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393
844 .word   0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25
845 .word   0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f
846 .word   0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1
847 .word   0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6
848 .word   0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da
849 .word   0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844
850 .word   0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd
851 .word   0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4
852 .word   0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45
853 .word   0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94
854 .word   0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7
855 .word   0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a
856 .word   0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5
857 .word   0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c
858 .word   0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1
859 .word   0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a
860 .word   0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75
861 .word   0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051
862 .word   0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46
863 .word   0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff
864 .word   0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77
865 .word   0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb
866 .word   0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000
867 .word   0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e
868 .word   0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927
869 .word   0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a
870 .word   0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e
871 .word   0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16
872 .word   0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d
873 .word   0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8
874 .word   0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd
875 .word   0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34
876 .word   0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163
877 .word   0xd731dcca, 0x42638510, 0x13972240, 0x84c61120
878 .word   0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d
879 .word   0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0
880 .word   0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422
881 .word   0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef
882 .word   0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36
883 .word   0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4
884 .word   0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662
885 .word   0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5
886 .word   0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3
887 .word   0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b
888 .word   0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8
889 .word   0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6
890 .word   0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6
891 .word   0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0
892 .word   0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815
893 .word   0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f
894 .word   0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df
895 .word   0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f
896 .word   0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e
897 .word   0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713
898 .word   0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89
899 .word   0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c
900 .word   0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf
901 .word   0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86
902 .word   0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f
903 .word   0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541
904 .word   0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190
905 .word   0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742
906 @ Td4[256]
907 .byte   0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
908 .byte   0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
909 .byte   0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
910 .byte   0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
911 .byte   0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
912 .byte   0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
913 .byte   0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
914 .byte   0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
915 .byte   0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
916 .byte   0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
917 .byte   0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
918 .byte   0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
919 .byte   0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
920 .byte   0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
921 .byte   0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
922 .byte   0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
923 .byte   0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
924 .byte   0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
925 .byte   0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
926 .byte   0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
927 .byte   0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
928 .byte   0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
929 .byte   0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
930 .byte   0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
931 .byte   0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
932 .byte   0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
933 .byte   0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
934 .byte   0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
935 .byte   0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
936 .byte   0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
937 .byte   0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
938 .byte   0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
939 .size   AES_Td,.-AES_Td
940
941 @ void AES_decrypt(const unsigned char *in, unsigned char *out,
942 @                const AES_KEY *key) {
943 .global AES_decrypt
944 .type   AES_decrypt,%function
945 .align  5
946 AES_decrypt:
947 #if __ARM_ARCH__<7
948         sub     r3,pc,#8                @ AES_decrypt
949 #else
950         adr     r3,AES_decrypt
951 #endif
952         stmdb   sp!,{r1,r4-r12,lr}
953         mov     $rounds,r0              @ inp
954         mov     $key,r2
955         sub     $tbl,r3,#AES_decrypt-AES_Td             @ Td
956 #if __ARM_ARCH__<7
957         ldrb    $s0,[$rounds,#3]        @ load input data in endian-neutral
958         ldrb    $t1,[$rounds,#2]        @ manner...
959         ldrb    $t2,[$rounds,#1]
960         ldrb    $t3,[$rounds,#0]
961         orr     $s0,$s0,$t1,lsl#8
962         ldrb    $s1,[$rounds,#7]
963         orr     $s0,$s0,$t2,lsl#16
964         ldrb    $t1,[$rounds,#6]
965         orr     $s0,$s0,$t3,lsl#24
966         ldrb    $t2,[$rounds,#5]
967         ldrb    $t3,[$rounds,#4]
968         orr     $s1,$s1,$t1,lsl#8
969         ldrb    $s2,[$rounds,#11]
970         orr     $s1,$s1,$t2,lsl#16
971         ldrb    $t1,[$rounds,#10]
972         orr     $s1,$s1,$t3,lsl#24
973         ldrb    $t2,[$rounds,#9]
974         ldrb    $t3,[$rounds,#8]
975         orr     $s2,$s2,$t1,lsl#8
976         ldrb    $s3,[$rounds,#15]
977         orr     $s2,$s2,$t2,lsl#16
978         ldrb    $t1,[$rounds,#14]
979         orr     $s2,$s2,$t3,lsl#24
980         ldrb    $t2,[$rounds,#13]
981         ldrb    $t3,[$rounds,#12]
982         orr     $s3,$s3,$t1,lsl#8
983         orr     $s3,$s3,$t2,lsl#16
984         orr     $s3,$s3,$t3,lsl#24
985 #else
986         ldr     $s0,[$rounds,#0]
987         ldr     $s1,[$rounds,#4]
988         ldr     $s2,[$rounds,#8]
989         ldr     $s3,[$rounds,#12]
990 #ifdef __ARMEL__
991         rev     $s0,$s0
992         rev     $s1,$s1
993         rev     $s2,$s2
994         rev     $s3,$s3
995 #endif
996 #endif
997         bl      _armv4_AES_decrypt
998
999         ldr     $rounds,[sp],#4         @ pop out
1000 #if __ARM_ARCH__>=7
1001 #ifdef __ARMEL__
1002         rev     $s0,$s0
1003         rev     $s1,$s1
1004         rev     $s2,$s2
1005         rev     $s3,$s3
1006 #endif
1007         str     $s0,[$rounds,#0]
1008         str     $s1,[$rounds,#4]
1009         str     $s2,[$rounds,#8]
1010         str     $s3,[$rounds,#12]
1011 #else
1012         mov     $t1,$s0,lsr#24          @ write output in endian-neutral
1013         mov     $t2,$s0,lsr#16          @ manner...
1014         mov     $t3,$s0,lsr#8
1015         strb    $t1,[$rounds,#0]
1016         strb    $t2,[$rounds,#1]
1017         mov     $t1,$s1,lsr#24
1018         strb    $t3,[$rounds,#2]
1019         mov     $t2,$s1,lsr#16
1020         strb    $s0,[$rounds,#3]
1021         mov     $t3,$s1,lsr#8
1022         strb    $t1,[$rounds,#4]
1023         strb    $t2,[$rounds,#5]
1024         mov     $t1,$s2,lsr#24
1025         strb    $t3,[$rounds,#6]
1026         mov     $t2,$s2,lsr#16
1027         strb    $s1,[$rounds,#7]
1028         mov     $t3,$s2,lsr#8
1029         strb    $t1,[$rounds,#8]
1030         strb    $t2,[$rounds,#9]
1031         mov     $t1,$s3,lsr#24
1032         strb    $t3,[$rounds,#10]
1033         mov     $t2,$s3,lsr#16
1034         strb    $s2,[$rounds,#11]
1035         mov     $t3,$s3,lsr#8
1036         strb    $t1,[$rounds,#12]
1037         strb    $t2,[$rounds,#13]
1038         strb    $t3,[$rounds,#14]
1039         strb    $s3,[$rounds,#15]
1040 #endif
1041 #if __ARM_ARCH__>=5
1042         ldmia   sp!,{r4-r12,pc}
1043 #else
1044         ldmia   sp!,{r4-r12,lr}
1045         tst     lr,#1
1046         moveq   pc,lr                   @ be binary compatible with V4, yet
1047         bx      lr                      @ interoperable with Thumb ISA:-)
1048 #endif
1049 .size   AES_decrypt,.-AES_decrypt
1050
1051 .type   _armv4_AES_decrypt,%function
1052 .align  2
1053 _armv4_AES_decrypt:
1054         str     lr,[sp,#-4]!            @ push lr
1055         ldmia   $key!,{$t1-$i1}
1056         eor     $s0,$s0,$t1
1057         ldr     $rounds,[$key,#240-16]
1058         eor     $s1,$s1,$t2
1059         eor     $s2,$s2,$t3
1060         eor     $s3,$s3,$i1
1061         sub     $rounds,$rounds,#1
1062         mov     lr,#255
1063
1064         and     $i1,lr,$s0,lsr#16
1065         and     $i2,lr,$s0,lsr#8
1066         and     $i3,lr,$s0
1067         mov     $s0,$s0,lsr#24
1068 .Ldec_loop:
1069         ldr     $t1,[$tbl,$i1,lsl#2]    @ Td1[s0>>16]
1070         and     $i1,lr,$s1              @ i0
1071         ldr     $t2,[$tbl,$i2,lsl#2]    @ Td2[s0>>8]
1072         and     $i2,lr,$s1,lsr#16
1073         ldr     $t3,[$tbl,$i3,lsl#2]    @ Td3[s0>>0]
1074         and     $i3,lr,$s1,lsr#8
1075         ldr     $s0,[$tbl,$s0,lsl#2]    @ Td0[s0>>24]
1076         mov     $s1,$s1,lsr#24
1077
1078         ldr     $i1,[$tbl,$i1,lsl#2]    @ Td3[s1>>0]
1079         ldr     $i2,[$tbl,$i2,lsl#2]    @ Td1[s1>>16]
1080         ldr     $i3,[$tbl,$i3,lsl#2]    @ Td2[s1>>8]
1081         eor     $s0,$s0,$i1,ror#24
1082         ldr     $s1,[$tbl,$s1,lsl#2]    @ Td0[s1>>24]
1083         and     $i1,lr,$s2,lsr#8        @ i0
1084         eor     $t2,$i2,$t2,ror#8
1085         and     $i2,lr,$s2              @ i1
1086         eor     $t3,$i3,$t3,ror#8
1087         and     $i3,lr,$s2,lsr#16
1088         ldr     $i1,[$tbl,$i1,lsl#2]    @ Td2[s2>>8]
1089         eor     $s1,$s1,$t1,ror#8
1090         ldr     $i2,[$tbl,$i2,lsl#2]    @ Td3[s2>>0]
1091         mov     $s2,$s2,lsr#24
1092
1093         ldr     $i3,[$tbl,$i3,lsl#2]    @ Td1[s2>>16]
1094         eor     $s0,$s0,$i1,ror#16
1095         ldr     $s2,[$tbl,$s2,lsl#2]    @ Td0[s2>>24]
1096         and     $i1,lr,$s3,lsr#16       @ i0
1097         eor     $s1,$s1,$i2,ror#24
1098         and     $i2,lr,$s3,lsr#8        @ i1
1099         eor     $t3,$i3,$t3,ror#8
1100         and     $i3,lr,$s3              @ i2
1101         ldr     $i1,[$tbl,$i1,lsl#2]    @ Td1[s3>>16]
1102         eor     $s2,$s2,$t2,ror#8
1103         ldr     $i2,[$tbl,$i2,lsl#2]    @ Td2[s3>>8]
1104         mov     $s3,$s3,lsr#24
1105
1106         ldr     $i3,[$tbl,$i3,lsl#2]    @ Td3[s3>>0]
1107         eor     $s0,$s0,$i1,ror#8
1108         ldr     $i1,[$key],#16
1109         eor     $s1,$s1,$i2,ror#16
1110         ldr     $s3,[$tbl,$s3,lsl#2]    @ Td0[s3>>24]
1111         eor     $s2,$s2,$i3,ror#24
1112
1113         ldr     $t1,[$key,#-12]
1114         eor     $s0,$s0,$i1
1115         ldr     $t2,[$key,#-8]
1116         eor     $s3,$s3,$t3,ror#8
1117         ldr     $t3,[$key,#-4]
1118         and     $i1,lr,$s0,lsr#16
1119         eor     $s1,$s1,$t1
1120         and     $i2,lr,$s0,lsr#8
1121         eor     $s2,$s2,$t2
1122         and     $i3,lr,$s0
1123         eor     $s3,$s3,$t3
1124         mov     $s0,$s0,lsr#24
1125
1126         subs    $rounds,$rounds,#1
1127         bne     .Ldec_loop
1128
1129         add     $tbl,$tbl,#1024
1130
1131         ldr     $t2,[$tbl,#0]           @ prefetch Td4
1132         ldr     $t3,[$tbl,#32]
1133         ldr     $t1,[$tbl,#64]
1134         ldr     $t2,[$tbl,#96]
1135         ldr     $t3,[$tbl,#128]
1136         ldr     $t1,[$tbl,#160]
1137         ldr     $t2,[$tbl,#192]
1138         ldr     $t3,[$tbl,#224]
1139
1140         ldrb    $s0,[$tbl,$s0]          @ Td4[s0>>24]
1141         ldrb    $t1,[$tbl,$i1]          @ Td4[s0>>16]
1142         and     $i1,lr,$s1              @ i0
1143         ldrb    $t2,[$tbl,$i2]          @ Td4[s0>>8]
1144         and     $i2,lr,$s1,lsr#16
1145         ldrb    $t3,[$tbl,$i3]          @ Td4[s0>>0]
1146         and     $i3,lr,$s1,lsr#8
1147
1148         add     $s1,$tbl,$s1,lsr#24
1149         ldrb    $i1,[$tbl,$i1]          @ Td4[s1>>0]
1150         ldrb    $s1,[$s1]               @ Td4[s1>>24]
1151         ldrb    $i2,[$tbl,$i2]          @ Td4[s1>>16]
1152         eor     $s0,$i1,$s0,lsl#24
1153         ldrb    $i3,[$tbl,$i3]          @ Td4[s1>>8]
1154         eor     $s1,$t1,$s1,lsl#8
1155         and     $i1,lr,$s2,lsr#8        @ i0
1156         eor     $t2,$t2,$i2,lsl#8
1157         and     $i2,lr,$s2              @ i1
1158         ldrb    $i1,[$tbl,$i1]          @ Td4[s2>>8]
1159         eor     $t3,$t3,$i3,lsl#8
1160         ldrb    $i2,[$tbl,$i2]          @ Td4[s2>>0]
1161         and     $i3,lr,$s2,lsr#16
1162
1163         add     $s2,$tbl,$s2,lsr#24
1164         ldrb    $s2,[$s2]               @ Td4[s2>>24]
1165         eor     $s0,$s0,$i1,lsl#8
1166         ldrb    $i3,[$tbl,$i3]          @ Td4[s2>>16]
1167         eor     $s1,$i2,$s1,lsl#16
1168         and     $i1,lr,$s3,lsr#16       @ i0
1169         eor     $s2,$t2,$s2,lsl#16
1170         and     $i2,lr,$s3,lsr#8        @ i1
1171         ldrb    $i1,[$tbl,$i1]          @ Td4[s3>>16]
1172         eor     $t3,$t3,$i3,lsl#16
1173         ldrb    $i2,[$tbl,$i2]          @ Td4[s3>>8]
1174         and     $i3,lr,$s3              @ i2
1175
1176         add     $s3,$tbl,$s3,lsr#24
1177         ldrb    $i3,[$tbl,$i3]          @ Td4[s3>>0]
1178         ldrb    $s3,[$s3]               @ Td4[s3>>24]
1179         eor     $s0,$s0,$i1,lsl#16
1180         ldr     $i1,[$key,#0]
1181         eor     $s1,$s1,$i2,lsl#8
1182         ldr     $t1,[$key,#4]
1183         eor     $s2,$i3,$s2,lsl#8
1184         ldr     $t2,[$key,#8]
1185         eor     $s3,$t3,$s3,lsl#24
1186         ldr     $t3,[$key,#12]
1187
1188         eor     $s0,$s0,$i1
1189         eor     $s1,$s1,$t1
1190         eor     $s2,$s2,$t2
1191         eor     $s3,$s3,$t3
1192
1193         sub     $tbl,$tbl,#1024
1194         ldr     pc,[sp],#4              @ pop and return
1195 .size   _armv4_AES_decrypt,.-_armv4_AES_decrypt
1196 .asciz  "AES for ARMv4, CRYPTOGAMS by <appro\@openssl.org>"
1197 .align  2
1198 ___
1199
1200 $code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;    # make it possible to compile with -march=armv4
1201
1202 open SELF,$0;
1203 while(<SELF>) {
1204         next if (/^#!/);
1205         last if (!s/^#/@/ and !/^$/);
1206         print;
1207 }
1208 close SELF;
1209
1210 print $code;
1211 close STDOUT;   # enforce flush