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