Various minor updates to AES assembler modules.
[openssl.git] / crypto / aes / asm / aes-s390x.pl
1 #!/usr/bin/env perl
2
3 # ====================================================================
4 # Written by Andy Polyakov <appro@fy.chalmers.se> 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 s390x.
11
12 # April 2007.
13 #
14 # Software performance improvement over gcc-generated code is ~70% and
15 # in absolute terms is ~73 cycles per byte processed with 128-bit key.
16 # You're likely to exclaim "why so slow?" Keep in mind that z-CPUs are
17 # *strictly* in-order execution and issued instruction [in this case
18 # load value from memory is critical] has to complete before execution
19 # flow proceeds. S-boxes are compressed to 2KB[+256B].
20 #
21 # As for hardware acceleration support. It's basically a "teaser," as
22 # it can and should be improved in several ways. Most notably support
23 # for CBC is not utilized, nor multiple blocks are ever processed.
24 # Then software key schedule can be postponed till hardware support
25 # detection... Performance improvement over assembler is reportedly
26 # ~2.5x, but can reach >8x [naturally on larger chunks] if proper
27 # support is implemented.
28
29 # May 2007.
30 #
31 # Implement AES_set_[en|de]crypt_key. Key schedule setup is avoided
32 # for 128-bit keys, if hardware support is detected.
33
34 $t1="%r0";
35 $t2="%r1";
36 $t3="%r2";      $inp="%r2";
37 $out="%r3";     $mask="%r3";    $bits="%r3";
38 $key="%r4";
39 $i1="%r5";
40 $i2="%r6";
41 $i3="%r7";
42 $s0="%r8";
43 $s1="%r9";
44 $s2="%r10";
45 $s3="%r11";
46 $tbl="%r12";
47 $rounds="%r13";
48 $ra="%r14";
49 $sp="%r15";
50
51 sub _data_word()
52 { my $i;
53     while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; }
54 }
55
56 $code=<<___;
57 .text
58
59 .type   AES_Te,\@object
60 .align  64
61 AES_Te:
62 ___
63 &_data_word(
64         0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
65         0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
66         0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
67         0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
68         0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
69         0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
70         0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
71         0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
72         0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
73         0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
74         0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
75         0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
76         0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
77         0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
78         0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
79         0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
80         0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
81         0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
82         0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
83         0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
84         0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
85         0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
86         0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
87         0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
88         0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
89         0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
90         0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
91         0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
92         0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
93         0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
94         0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
95         0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
96         0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
97         0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
98         0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
99         0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
100         0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
101         0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
102         0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
103         0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
104         0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
105         0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
106         0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
107         0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
108         0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
109         0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
110         0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
111         0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
112         0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
113         0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
114         0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
115         0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
116         0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
117         0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
118         0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
119         0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
120         0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
121         0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
122         0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
123         0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
124         0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
125         0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
126         0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
127         0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a);
128 $code.=<<___;
129 # Te4[256]
130 .byte   0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
131 .byte   0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
132 .byte   0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
133 .byte   0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
134 .byte   0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
135 .byte   0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
136 .byte   0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
137 .byte   0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
138 .byte   0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
139 .byte   0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
140 .byte   0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
141 .byte   0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
142 .byte   0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
143 .byte   0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
144 .byte   0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
145 .byte   0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
146 .byte   0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
147 .byte   0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
148 .byte   0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
149 .byte   0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
150 .byte   0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
151 .byte   0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
152 .byte   0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
153 .byte   0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
154 .byte   0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
155 .byte   0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
156 .byte   0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
157 .byte   0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
158 .byte   0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
159 .byte   0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
160 .byte   0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
161 .byte   0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
162 # rcon[]
163 .long   0x01000000, 0x02000000, 0x04000000, 0x08000000
164 .long   0x10000000, 0x20000000, 0x40000000, 0x80000000
165 .long   0x1B000000, 0x36000000, 0, 0, 0, 0, 0, 0
166 .size   AES_Te,.-AES_Te
167
168 # void AES_encrypt(const unsigned char *inp, unsigned char *out,
169 #                const AES_KEY *key) {
170 .globl  AES_encrypt
171 .type   AES_encrypt,\@function
172 AES_encrypt:
173         stg     $ra,112($sp)
174         lghi    %r0,10
175         c       %r0,240($key)
176         jne     .Lesoft
177         lghi    %r0,0           # query capability vector
178         la      %r1,16($sp)
179         .long   0xb92e0042      # km %r4,%r2
180         lg      %r0,16($sp)
181         tmhl    %r0,`0x8000>>2`
182         jz      .Lesoft128
183         lghi    %r0,`0x00|0x12` # encrypt AES-128
184         la      %r1,0($key)
185         #la     %r2,0($inp)
186         la      %r4,0($out)
187         lghi    %r3,16          # single block length
188         .long   0xb92e0042      # km %r4,%r2
189         bcr     8,%r14          # return if done
190         la      $out,0(%r4)     # restore arguments
191         la      $key,0(%r1)
192 .Lesoft128:
193         lghi    %r0,0
194         c       %r0,236($key)
195         je      .Lesoft
196         stmg    $inp,$key,16($sp)
197         la      $inp,0($key)
198         lghi    $bits,128
199         bras    $ra,.Lekey_internal     # postponed key schedule setup
200         lmg     $inp,$key,16($sp)
201 .Lesoft:
202         stmg    %r3,%r13,24($sp)
203
204         bras    $tbl,1f
205 1:      aghi    $tbl,AES_Te-.
206
207         llgf    $s0,0($inp)
208         llgf    $s1,4($inp)
209         llgf    $s2,8($inp)
210         llgf    $s3,12($inp)
211
212         llill   $mask,`0xff<<3`
213         bras    $ra,_s390x_AES_encrypt
214
215         lg      $out,24($sp)
216         st      $s0,0($out)
217         st      $s1,4($out)
218         st      $s2,8($out)
219         st      $s3,12($out)
220
221         lmg     %r6,$ra,48($sp)
222         br      $ra
223 .size   AES_encrypt,.-AES_encrypt
224
225 .type   _s390x_AES_encrypt,\@function
226 .align  16
227 _s390x_AES_encrypt:
228         x       $s0,0($key)
229         x       $s1,4($key)
230         x       $s2,8($key)
231         x       $s3,12($key)
232         l       $rounds,240($key)
233         aghi    $rounds,-1
234
235 .Lenc_loop:
236         sllg    $i1,$s0,`0+3`
237         srlg    $i2,$s0,`8-3`
238         srlg    $i3,$s0,`16-3`
239         srl     $s0,`24-3`
240         nr      $s0,$mask
241         ngr     $i1,$mask
242         nr      $i2,$mask
243         nr      $i3,$mask
244         l       $s0,0($s0,$tbl) # Te0[s0>>24]
245         l       $t1,1($i1,$tbl) # Te3[s0>>0]
246         l       $t2,2($i2,$tbl) # Te2[s0>>8]
247         l       $t3,3($i3,$tbl) # Te1[s0>>16]
248
249         srlg    $i1,$s1,`16-3`  # i0
250         sllg    $i2,$s1,`0+3`
251         srlg    $i3,$s1,`8-3`
252         srl     $s1,`24-3`
253         nr      $i1,$mask
254         nr      $s1,$mask
255         ngr     $i2,$mask
256         nr      $i3,$mask
257         x       $s0,3($i1,$tbl) # Te1[s1>>16]
258         l       $s1,0($s1,$tbl) # Te0[s1>>24]
259         x       $t2,1($i2,$tbl) # Te3[s1>>0]
260         x       $t3,2($i3,$tbl) # Te2[s1>>8]
261         xr      $s1,$t1
262
263         srlg    $i1,$s2,`8-3`   # i0
264         srlg    $i2,$s2,`16-3`  # i1
265         sllg    $i3,$s2,`0+3`
266         srl     $s2,`24-3`
267         nr      $i1,$mask
268         nr      $i2,$mask
269         nr      $s2,$mask
270         ngr     $i3,$mask
271         x       $s0,2($i1,$tbl) # Te2[s2>>8]
272         x       $s1,3($i2,$tbl) # Te1[s2>>16]
273         l       $s2,0($s2,$tbl) # Te0[s2>>24]
274         x       $t3,1($i3,$tbl) # Te3[s2>>0]
275         xr      $s2,$t2
276
277         sllg    $i1,$s3,`0+3`   # i0
278         srlg    $i2,$s3,`8-3`   # i1
279         srlg    $i3,$s3,`16-3`  # i2
280         srl     $s3,`24-3`
281         ngr     $i1,$mask
282         nr      $i2,$mask
283         nr      $i3,$mask
284         nr      $s3,$mask
285         x       $s0,1($i1,$tbl) # Te3[s3>>0]
286         x       $s1,2($i2,$tbl) # Te2[s3>>8]
287         x       $s2,3($i3,$tbl) # Te1[s3>>16]
288         l       $s3,0($s3,$tbl) # Te0[s3>>24]
289         xr      $s3,$t3
290
291         la      $key,16($key)
292         x       $s0,0($key)
293         x       $s1,4($key)
294         x       $s2,8($key)
295         x       $s3,12($key)
296
297         brct    $rounds,.Lenc_loop
298
299         sllg    $i1,$s0,`0+3`
300         srlg    $i2,$s0,`8-3`
301         srlg    $i3,$s0,`16-3`
302         srl     $s0,`24-3`
303         nr      $s0,$mask
304         ngr     $i1,$mask
305         nr      $i2,$mask
306         nr      $i3,$mask
307         llgc    $s0,2($s0,$tbl) # Te4[s0>>24]
308         llgc    $t1,2($i1,$tbl) # Te4[s0>>0]
309         llgc    $t2,2($i2,$tbl) # Te4[s0>>8]
310         llgc    $t3,2($i3,$tbl) # Te4[s0>>16]
311         sll     $s0,24
312         sll     $t2,8
313         sll     $t3,16
314
315         srlg    $i1,$s1,`16-3`  # i0
316         sllg    $i2,$s1,`0+3`
317         srlg    $i3,$s1,`8-3`
318         srl     $s1,`24-3`
319         nr      $i1,$mask
320         nr      $s1,$mask
321         ngr     $i2,$mask
322         nr      $i3,$mask
323         llgc    $i1,2($i1,$tbl) # Te4[s1>>16]
324         llgc    $s1,2($s1,$tbl) # Te4[s1>>24]
325         llgc    $i2,2($i2,$tbl) # Te4[s1>>0]
326         llgc    $i3,2($i3,$tbl) # Te4[s1>>8]
327         sll     $i1,16
328         sll     $s1,24
329         sll     $i3,8
330         or      $s0,$i1
331         or      $s1,$t1
332         or      $t2,$i2
333         or      $t3,$i3
334         
335         srlg    $i1,$s2,`8-3`   # i0
336         srlg    $i2,$s2,`16-3`  # i1
337         sllg    $i3,$s2,`0+3`
338         srl     $s2,`24-3`
339         nr      $i1,$mask
340         nr      $i2,$mask
341         nr      $s2,$mask
342         ngr     $i3,$mask
343         llgc    $i1,2($i1,$tbl) # Te4[s2>>8]
344         llgc    $i2,2($i2,$tbl) # Te4[s2>>16]
345         llgc    $s2,2($s2,$tbl) # Te4[s2>>24]
346         llgc    $i3,2($i3,$tbl) # Te4[s2>>0]
347         sll     $i1,8
348         sll     $i2,16
349         sll     $s2,24
350         or      $s0,$i1
351         or      $s1,$i2
352         or      $s2,$t2
353         or      $t3,$i3
354
355         sllg    $i1,$s3,`0+3`   # i0
356         srlg    $i2,$s3,`8-3`   # i1
357         srlg    $i3,$s3,`16-3`  # i2
358         srl     $s3,`24-3`
359         ngr     $i1,$mask
360         nr      $i2,$mask
361         nr      $i3,$mask
362         nr      $s3,$mask
363         llgc    $i1,2($i1,$tbl) # Te4[s3>>0]
364         llgc    $i2,2($i2,$tbl) # Te4[s3>>8]
365         llgc    $i3,2($i3,$tbl) # Te4[s3>>16]
366         llgc    $s3,2($s3,$tbl) # Te4[s3>>24]
367         sll     $i2,8
368         sll     $i3,16
369         sll     $s3,24
370         or      $s0,$i1
371         or      $s1,$i2
372         or      $s2,$i3
373         or      $s3,$t3
374
375         x       $s0,16($key)
376         x       $s1,20($key)
377         x       $s2,24($key)
378         x       $s3,28($key)
379
380         br      $ra     
381 .size   _s390x_AES_encrypt,.-_s390x_AES_encrypt
382 ___
383
384 $code.=<<___;
385 .type   AES_Td,\@object
386 .align  64
387 AES_Td:
388 ___
389 &_data_word(
390         0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
391         0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
392         0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
393         0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
394         0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
395         0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
396         0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
397         0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
398         0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
399         0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
400         0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
401         0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
402         0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
403         0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
404         0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
405         0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
406         0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
407         0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
408         0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
409         0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
410         0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
411         0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
412         0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
413         0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
414         0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
415         0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
416         0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
417         0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
418         0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
419         0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
420         0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
421         0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
422         0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
423         0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
424         0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
425         0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
426         0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
427         0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
428         0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
429         0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
430         0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
431         0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
432         0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
433         0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
434         0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
435         0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
436         0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
437         0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
438         0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
439         0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
440         0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
441         0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
442         0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
443         0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
444         0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
445         0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
446         0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
447         0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
448         0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
449         0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
450         0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
451         0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
452         0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
453         0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742);
454 $code.=<<___;
455 # Td4[256]
456 .byte   0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
457 .byte   0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
458 .byte   0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
459 .byte   0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
460 .byte   0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
461 .byte   0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
462 .byte   0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
463 .byte   0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
464 .byte   0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
465 .byte   0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
466 .byte   0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
467 .byte   0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
468 .byte   0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
469 .byte   0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
470 .byte   0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
471 .byte   0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
472 .byte   0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
473 .byte   0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
474 .byte   0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
475 .byte   0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
476 .byte   0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
477 .byte   0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
478 .byte   0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
479 .byte   0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
480 .byte   0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
481 .byte   0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
482 .byte   0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
483 .byte   0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
484 .byte   0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
485 .byte   0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
486 .byte   0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
487 .byte   0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
488 .size   AES_Td,.-AES_Td
489
490 # void AES_decrypt(const unsigned char *inp, unsigned char *out,
491 #                const AES_KEY *key) {
492 .globl  AES_decrypt
493 .type   AES_decrypt,\@function
494 AES_decrypt:
495         stg     $ra,112($sp)
496         lghi    %r0,10
497         c       %r0,240($key)
498         jne     .Ldsoft
499         lghi    %r0,0           # query capability vector
500         la      %r1,16($sp)
501         .long   0xb92e0042      # km %r4,%r2
502         lg      %r0,16($sp)
503         tmhl    %r0,`0x8000>>2`
504         jz      .Ldsoft128
505         lghi    %r0,`0x80|0x12` # decrypt AES-128
506         la      %r1,160($key)
507         #la     %r2,0($inp)
508         la      %r4,0($out)
509         lghi    %r3,16          # single block length
510         .long   0xb92e0042      # km %r4,%r2
511         bcr     8,%r14          # return if done
512         la      $out,0(%r4)     # restore arguments
513         lghi    $key,-160
514         la      $key,0($key,%r1)
515 .Ldsoft128:
516         lghi    %r0,0
517         c       %r0,236($key)
518         je      .Ldsoft
519         stmg    $inp,$key,16($sp)
520         la      $inp,160($key)
521         lghi    $bits,128
522         bras    $ra,.Ldkey_internal     # postponed key schedule setup
523         lmg     $inp,$key,16($sp)
524 .Ldsoft:
525         stmg    %r3,%r13,24($sp)
526
527         bras    $tbl,1f
528 1:      aghi    $tbl,AES_Td-.
529
530         llgf    $s0,0($inp)
531         llgf    $s1,4($inp)
532         llgf    $s2,8($inp)
533         llgf    $s3,12($inp)
534
535         llill   $mask,`0xff<<3`
536         bras    $ra,_s390x_AES_decrypt
537
538         lg      $out,24($sp)
539         st      $s0,0($out)
540         st      $s1,4($out)
541         st      $s2,8($out)
542         st      $s3,12($out)
543
544         lmg     %r6,$ra,48($sp)
545         br      $ra
546 .size   AES_decrypt,.-AES_decrypt
547
548 .type   _s390x_AES_decrypt,\@function
549 .align  16
550 _s390x_AES_decrypt:
551         x       $s0,0($key)
552         x       $s1,4($key)
553         x       $s2,8($key)
554         x       $s3,12($key)
555         l       $rounds,240($key)
556         aghi    $rounds,-1
557
558 .Ldec_loop:
559         srlg    $i1,$s0,`16-3`
560         srlg    $i2,$s0,`8-3`
561         sllg    $i3,$s0,`0+3`
562         srl     $s0,`24-3`
563         nr      $s0,$mask
564         nr      $i1,$mask
565         nr      $i2,$mask
566         ngr     $i3,$mask
567         l       $s0,0($s0,$tbl) # Td0[s0>>24]
568         l       $t1,3($i1,$tbl) # Td1[s0>>16]
569         l       $t2,2($i2,$tbl) # Td2[s0>>8]
570         l       $t3,1($i3,$tbl) # Td3[s0>>0]
571
572         sllg    $i1,$s1,`0+3`   # i0
573         srlg    $i2,$s1,`16-3`
574         srlg    $i3,$s1,`8-3`
575         srl     $s1,`24-3`
576         ngr     $i1,$mask
577         nr      $s1,$mask
578         nr      $i2,$mask
579         nr      $i3,$mask
580         x       $s0,1($i1,$tbl) # Td3[s1>>0]
581         l       $s1,0($s1,$tbl) # Td0[s1>>24]
582         x       $t2,3($i2,$tbl) # Td1[s1>>16]
583         x       $t3,2($i3,$tbl) # Td2[s1>>8]
584         xr      $s1,$t1
585
586         srlg    $i1,$s2,`8-3`   # i0
587         sllg    $i2,$s2,`0+3`   # i1
588         srlg    $i3,$s2,`16-3`
589         srl     $s2,`24-3`
590         nr      $i1,$mask
591         ngr     $i2,$mask
592         nr      $s2,$mask
593         nr      $i3,$mask
594         x       $s0,2($i1,$tbl) # Td2[s2>>8]
595         x       $s1,1($i2,$tbl) # Td3[s2>>0]
596         l       $s2,0($s2,$tbl) # Td0[s2>>24]
597         x       $t3,3($i3,$tbl) # Td1[s2>>16]
598         xr      $s2,$t2
599
600         srlg    $i1,$s3,`16-3`  # i0
601         srlg    $i2,$s3,`8-3`   # i1
602         sllg    $i3,$s3,`0+3`   # i2
603         srl     $s3,`24-3`
604         nr      $i1,$mask
605         nr      $i2,$mask
606         ngr     $i3,$mask
607         nr      $s3,$mask
608         x       $s0,3($i1,$tbl) # Td1[s3>>16]
609         x       $s1,2($i2,$tbl) # Td2[s3>>8]
610         x       $s2,1($i3,$tbl) # Td3[s3>>0]
611         l       $s3,0($s3,$tbl) # Td0[s3>>24]
612         xr      $s3,$t3
613
614         la      $key,16($key)
615         x       $s0,0($key)
616         x       $s1,4($key)
617         x       $s2,8($key)
618         x       $s3,12($key)
619
620         brct    $rounds,.Ldec_loop
621
622         l       $t1,`2048+0`($tbl)      # prefetch Td4
623         l       $t2,`2048+32`($tbl)
624         l       $t3,`2048+64`($tbl)
625         l       $i1,`2048+96`($tbl)
626         l       $i2,`2048+128`($tbl)
627         l       $i3,`2048+160`($tbl)
628         l       $t1,`2048+192`($tbl)
629         l       $t2,`2048+224`($tbl)
630         llill   $mask,0xff
631
632         srlg    $i3,$s0,24      # i0
633         srlg    $i1,$s0,16
634         srlg    $i2,$s0,8
635         nr      $s0,$mask       # i3
636         nr      $i1,$mask
637         nr      $i2,$mask
638         llgc    $i3,2048($i3,$tbl)      # Td4[s0>>24]
639         llgc    $t1,2048($i1,$tbl)      # Td4[s0>>16]
640         llgc    $t2,2048($i2,$tbl)      # Td4[s0>>8]
641         llgc    $t3,2048($s0,$tbl)      # Td4[s0>>0]
642         sllg    $s0,$i3,24
643         sll     $t1,16
644         sll     $t2,8
645
646         srlg    $i1,$s1,24
647         srlg    $i2,$s1,16
648         srlg    $i3,$s1,8
649         nr      $s1,$mask       # i0
650         nr      $i2,$mask
651         nr      $i3,$mask
652         llgc    $s1,2048($s1,$tbl)      # Td4[s1>>0]
653         llgc    $i1,2048($i1,$tbl)      # Td4[s1>>24]
654         llgc    $i2,2048($i2,$tbl)      # Td4[s1>>16]
655         llgc    $i3,2048($i3,$tbl)      # Td4[s1>>8]
656         sll     $i1,24
657         sll     $i2,16
658         sll     $i3,8
659         or      $s0,$s1
660         or      $t1,$i1
661         or      $t2,$i2
662         or      $t3,$i3
663
664         srlg    $i1,$s2,8       # i0
665         srlg    $i2,$s2,24
666         srlg    $i3,$s2,16
667         nr      $s2,$mask       # i1
668         nr      $i1,$mask
669         nr      $i3,$mask
670         llgc    $i1,2048($i1,$tbl)      # Td4[s2>>8]
671         llgc    $s1,2048($s2,$tbl)      # Td4[s2>>0]
672         llgc    $i2,2048($i2,$tbl)      # Td4[s2>>24]
673         llgc    $i3,2048($i3,$tbl)      # Td4[s2>>16]
674         sll     $i1,8
675         sll     $i2,24
676         sll     $i3,16
677         or      $s0,$i1
678         or      $s1,$t1
679         or      $t2,$i2
680         or      $t3,$i3
681
682         srlg    $i1,$s3,16      # i0
683         srlg    $i2,$s3,8       # i1
684         srlg    $i3,$s3,24
685         nr      $s3,$mask       # i2
686         nr      $i1,$mask
687         nr      $i2,$mask
688         llgc    $i1,2048($i1,$tbl)      # Td4[s3>>16]
689         llgc    $i2,2048($i2,$tbl)      # Td4[s3>>8]
690         llgc    $s2,2048($s3,$tbl)      # Td4[s3>>0]
691         llgc    $s3,2048($i3,$tbl)      # Td4[s3>>24]
692         sll     $i1,16
693         sll     $i2,8
694         sll     $s3,24
695         or      $s0,$i1
696         or      $s1,$i2
697         or      $s2,$t2
698         or      $s3,$t3
699
700         x       $s0,16($key)
701         x       $s1,20($key)
702         x       $s2,24($key)
703         x       $s3,28($key)
704
705         br      $ra     
706 .size   _s390x_AES_decrypt,.-_s390x_AES_decrypt
707
708 # void AES_set_encrypt_key(const unsigned char *in, int bits,
709 #                AES_KEY *key) {
710 .globl  AES_set_encrypt_key
711 .type   AES_set_encrypt_key,\@function
712 .align  16
713 AES_set_encrypt_key:
714         lghi    $t1,0
715         clgr    $inp,$t1
716         je      .Lminus1
717         clgr    $key,$t1
718         je      .Lminus1
719
720         lghi    $t1,128
721         clr     $bits,$t1
722         je      .Lproceed128
723         lghi    $t1,192
724         clr     $bits,$t1
725         je      .Lekey_internal
726         lghi    $t1,256
727         clr     $bits,$t1
728         je      .Lekey_internal
729         lghi    %r2,-2
730         br      %r14
731
732 .align  4
733 .Lproceed128:
734         lghi    %r0,0           # query capability vector
735         la      %r1,16($sp)
736         .long   0xb92e0042      # km %r4,%r2
737         lg      %r0,16($sp)
738         tmhl    %r0,`0x8000>>2`
739         jz      .Lekey_internal
740
741         lmg     $t1,$t2,0($inp) # just copy 128 bits...
742         stmg    $t1,$t2,0($key)
743         lghi    $t1,10
744         st      $t1,236($key)   # ... postpone key setup
745         st      $t1,240($key)
746         lghi    %r2,0
747         br      %r14
748
749 .align  16
750 .Lekey_internal:
751         stmg    %r6,%r13,48($sp)        # all non-volatile regs
752
753         bras    $tbl,1f
754 1:      aghi    $tbl,AES_Te+2048-.
755
756         llgf    $s0,0($inp)
757         llgf    $s1,4($inp)
758         llgf    $s2,8($inp)
759         llgf    $s3,12($inp)
760         st      $s0,0($key)
761         st      $s1,4($key)
762         st      $s2,8($key)
763         st      $s3,12($key)
764         lghi    $t1,128
765         cr      $bits,$t1
766         jne     .Lnot128
767
768         llill   $mask,0xff
769         lghi    $t3,0                   # i=0
770         lghi    $rounds,10
771         st      $t3,236($key)           # mark as set up
772         st      $rounds,240($key)
773
774 .align  8
775 .L128_loop:
776         llgfr   $t2,$s3                 # temp=rk[3]
777         srlg    $i1,$s3,8
778         srlg    $i2,$s3,16
779         srlg    $i3,$s3,24
780         nr      $t2,$mask
781         nr      $i1,$mask
782         nr      $i2,$mask
783         la      $t2,0($t2,$tbl)
784         la      $i1,0($i1,$tbl)
785         la      $i2,0($i2,$tbl)
786         la      $i3,0($i3,$tbl)
787         icm     $t2,2,0($t2)            # Te4[rk[3]>>0]<<8
788         icm     $t2,4,0($i1)            # Te4[rk[3]>>8]<<16
789         icm     $t2,8,0($i2)            # Te4[rk[3]>>16]<<24
790         icm     $t2,1,0($i3)            # Te4[rk[3]>>24]
791         x       $t2,256($t3,$tbl)       # rcon[i]
792         xr      $s0,$t2                 # rk[4]=rk[0]^...
793         xr      $s1,$s0                 # rk[5]=rk[1]^rk[4]
794         xr      $s2,$s1                 # rk[6]=rk[2]^rk[5]
795         xr      $s3,$s2                 # rk[7]=rk[3]^rk[6]
796         st      $s0,16($key)
797         st      $s1,20($key)
798         st      $s2,24($key)
799         st      $s3,28($key)
800         la      $key,16($key)           # key+=4
801         la      $t3,4($t3)              # i++
802         brct    $rounds,.L128_loop
803         lghi    %r2,0
804         lmg     %r6,%r13,48($sp)
805         br      $ra
806
807 .align  4
808 .Lnot128:
809         llgf    $t1,16($inp)
810         llgf    $t2,20($inp)
811         st      $t1,16($key)
812         st      $t2,20($key)
813         lghi    $t1,192
814         cr      $bits,$t1
815         jne     .Lnot192
816
817         llill   $mask,0xff
818         lghi    $t3,0                   # i=0
819         lghi    $rounds,12
820         st      $rounds,240($key)
821         lghi    $rounds,8
822
823 .align  8
824 .L192_loop:
825         srlg    $i1,$t2,8
826         srlg    $i2,$t2,16
827         srlg    $i3,$t2,24
828         nr      $t2,$mask
829         nr      $i1,$mask
830         nr      $i2,$mask
831         la      $t2,0($t2,$tbl)
832         la      $i1,0($i1,$tbl)
833         la      $i2,0($i2,$tbl)
834         la      $i3,0($i3,$tbl)
835         icm     $t2,2,0($t2)            # Te4[rk[5]>>0]<<8
836         icm     $t2,4,0($i1)            # Te4[rk[5]>>8]<<16
837         icm     $t2,8,0($i2)            # Te4[rk[5]>>16]<<24
838         icm     $t2,1,0($i3)            # Te4[rk[5]>>24]
839         x       $t2,256($t3,$tbl)       # rcon[i]
840         xr      $s0,$t2                 # rk[6]=rk[0]^...
841         xr      $s1,$s0                 # rk[7]=rk[1]^rk[6]
842         xr      $s2,$s1                 # rk[8]=rk[2]^rk[7]
843         xr      $s3,$s2                 # rk[9]=rk[3]^rk[8]
844         st      $s0,24($key)
845         st      $s1,28($key)
846         st      $s2,32($key)
847         st      $s3,36($key)
848         brct    $rounds,.L192_continue
849         lghi    %r2,0
850         lmg     %r6,%r13,48($sp)
851         br      $ra
852 .align  4
853 .L192_continue:
854         lgr     $t2,$s3
855         x       $t2,16($key)            # rk[10]=rk[4]^rk[9]
856         st      $t2,40($key)
857         x       $t2,20($key)            # rk[11]=rk[5]^rk[10]
858         st      $t2,44($key)
859         la      $key,24($key)           # key+=6
860         la      $t3,4($t3)              # i++
861         j       .L192_loop
862
863 .align  4
864 .Lnot192:
865         llgf    $t1,24($inp)
866         llgf    $t2,28($inp)
867         st      $t1,24($key)
868         st      $t2,28($key)
869         llill   $mask,0xff
870         lghi    $t3,0                   # i=0
871         lghi    $rounds,14
872         st      $rounds,240($key)
873         lghi    $rounds,7
874
875 .align  8
876 .L256_loop:
877         srlg    $i1,$t2,8
878         srlg    $i2,$t2,16
879         srlg    $i3,$t2,24
880         nr      $t2,$mask
881         nr      $i1,$mask
882         nr      $i2,$mask
883         la      $t2,0($t2,$tbl)
884         la      $i1,0($i1,$tbl)
885         la      $i2,0($i2,$tbl)
886         la      $i3,0($i3,$tbl)
887         icm     $t2,2,0($t2)            # Te4[rk[7]>>0]<<8
888         icm     $t2,4,0($i1)            # Te4[rk[7]>>8]<<16
889         icm     $t2,8,0($i2)            # Te4[rk[7]>>16]<<24
890         icm     $t2,1,0($i3)            # Te4[rk[7]>>24]
891         x       $t2,256($t3,$tbl)       # rcon[i]
892         xr      $s0,$t2                 # rk[8]=rk[0]^...
893         xr      $s1,$s0                 # rk[9]=rk[1]^rk[8]
894         xr      $s2,$s1                 # rk[10]=rk[2]^rk[9]
895         xr      $s3,$s2                 # rk[11]=rk[3]^rk[10]
896         st      $s0,32($key)
897         st      $s1,36($key)
898         st      $s2,40($key)
899         st      $s3,44($key)
900         brct    $rounds,.L256_continue
901         lghi    %r2,0
902         lmg     %r6,%r13,48($sp)
903         br      $ra
904 .align  4
905 .L256_continue:
906         lgr     $t2,$s3                 # temp=rk[11]
907         srlg    $i1,$s3,8
908         srlg    $i2,$s3,16
909         srlg    $i3,$s3,24
910         nr      $t2,$mask
911         nr      $i1,$mask
912         nr      $i2,$mask
913         la      $t2,0($t2,$tbl)
914         la      $i1,0($i1,$tbl)
915         la      $i2,0($i2,$tbl)
916         la      $i3,0($i3,$tbl)
917         icm     $t2,1,0($t2)            # Te4[rk[11]>>0]
918         icm     $t2,2,0($i1)            # Te4[rk[11]>>8]<<8
919         icm     $t2,4,0($i2)            # Te4[rk[11]>>16]<<16
920         icm     $t2,8,0($i3)            # Te4[rk[11]>>24]<<24
921         x       $t2,16($key)            # rk[12]=rk[4]^...
922         st      $t2,48($key)
923         x       $t2,20($key)            # rk[13]=rk[5]^rk[12]
924         st      $t2,52($key)
925         x       $t2,24($key)            # rk[14]=rk[6]^rk[13]
926         st      $t2,56($key)
927         x       $t2,28($key)            # rk[15]=rk[7]^rk[14]
928         st      $t2,60($key)
929
930         la      $key,32($key)           # key+=8
931         la      $t3,4($t3)              # i++
932         j       .L256_loop
933 .align  4
934 .Lminus1:
935         lghi    %r2,-1
936         br      %r14
937 .size   AES_set_encrypt_key,.-AES_set_encrypt_key
938
939 # void AES_set_decrypt_key(const unsigned char *in, int bits,
940 #                AES_KEY *key) {
941 .globl  AES_set_decrypt_key
942 .type   AES_set_decrypt_key,\@function
943 .align  16
944 AES_set_decrypt_key:
945         stg     $key,32($sp)            # I rely on AES_set_encrypt_key to
946         stg     $ra,112($sp)            # save non-volatile registers!
947         bras    $ra,AES_set_encrypt_key
948         lg      $key,32($sp)
949         lg      $ra,112($sp)
950         ltgr    %r2,%r2
951         bnzr    $ra
952
953         lghi    $t1,10
954         c       $t1,240($key)
955         jne     .Lgo
956         lghi    $t1,0
957         c       $t1,236($key)
958         je      .Lgo
959
960         lmg     $t1,$t2,0($key)         # just copy 128 bits otherwise
961         stmg    $t1,$t2,160($key)
962         lghi    %r2,0
963         br      $ra
964
965 .align  16
966 .Ldkey_internal:
967         stg     $key,32($sp)
968         stg     $ra,40($sp)
969         bras    $ra,.Lekey_internal
970         lg      $key,32($sp)
971         lg      $ra,40($sp)
972
973 .Lgo:   llgf    $rounds,240($key)
974         la      $i1,0($key)
975         sllg    $i2,$rounds,4
976         la      $i2,0($i2,$key)
977         srl     $rounds,1
978
979 .align  8
980 .Linv:  lmg     $s0,$s1,0($i1)
981         lmg     $s2,$s3,0($i2)
982         stmg    $s0,$s1,0($i2)
983         stmg    $s2,$s3,0($i1)
984         aghi    $i1,16
985         aghi    $i2,-16
986         brct    $rounds,.Linv
987 ___
988 $mask80=$i1;
989 $mask1b=$i2;
990 $maskfe=$i3;
991 $code.=<<___;
992         llgf    $rounds,240($key)
993         aghi    $rounds,-1
994         sll     $rounds,2       # (rounds-1)*4
995         llilh   $mask80,0x8080
996         oill    $mask80,0x8080
997         llilh   $mask1b,0x1b1b
998         oill    $mask1b,0x1b1b
999         llilh   $maskfe,0xfefe
1000         oill    $maskfe,0xfefe
1001
1002 .align  8
1003 .Lmix:  l       $s0,16($key)    # tp1
1004         lr      $s1,$s0
1005         ngr     $s1,$mask80
1006         srlg    $t1,$s1,7
1007         slr     $s1,$t1
1008         nr      $s1,$mask1b
1009         sllg    $t1,$s0,1
1010         nr      $t1,$maskfe
1011         xr      $s1,$t1         # tp2
1012
1013         lr      $s2,$s1
1014         ngr     $s2,$mask80
1015         srlg    $t1,$s2,7
1016         slr     $s2,$t1
1017         nr      $s2,$mask1b
1018         sllg    $t1,$s1,1
1019         nr      $t1,$maskfe
1020         xr      $s2,$t1         # tp4
1021
1022         lr      $s3,$s2
1023         ngr     $s3,$mask80
1024         srlg    $t1,$s3,7
1025         slr     $s3,$t1
1026         nr      $s3,$mask1b
1027         sllg    $t1,$s2,1
1028         nr      $t1,$maskfe
1029         xr      $s3,$t1         # tp8
1030
1031         xr      $s1,$s0         # tp2^tp1
1032         xr      $s2,$s0         # tp4^tp1
1033         rll     $s0,$s0,24      # = ROTATE(tp1,8)
1034         xr      $s0,$s1         # ^=tp2^tp1
1035         xr      $s0,$s2         # ^=tp4^tp1
1036         xr      $s0,$s3         # ^= tp8[^(tp4^tp1)^(tp2^tp1)=tp4^tp2]
1037         xr      $s1,$s3         # tp2^tp1^tp8
1038         rll     $s1,$s1,8
1039         xr      $s0,$s1         # ^= ROTATE(tp8^tp2^tp1,24)
1040         xr      $s2,$s3         # tp4^tp1^tp8
1041         rll     $s2,$s2,16
1042         xr      $s0,$s2         # ^= ROTATE(tp8^tp4^tp1,16)
1043         rll     $s3,$s3,24
1044         xr      $s0,$s3         # ^= ROTATE(tp8,8)
1045
1046         st      $s0,16($key)
1047         la      $key,4($key)
1048         brct    $rounds,.Lmix
1049
1050         lmg     %r6,%r13,48($sp)# as was saved by AES_set_encrypt_key!
1051         lghi    %r2,0
1052         br      $ra
1053 .size   AES_set_decrypt_key,.-AES_set_decrypt_key
1054 .string "AES for s390x, CRYPTOGAMS by <appro\@openssl.org>"
1055 ___
1056
1057 $code =~ s/\`([^\`]*)\`/eval $1/gem;
1058 print $code;