06cd8dff9b3e5e0c8c978195890e598bf4dd80a3
[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  128
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  128
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         l       $t1,0($inp)     # just copy 128 bits...
742         l       $t2,4($inp)
743         l       $bits,8($inp)
744         l       $inp,12($inp)
745         st      $t1,0($key)
746         st      $t2,4($key)
747         st      $bits,8($key)
748         st      $inp,12($key)
749         lghi    $t1,10
750         st      $t1,236($key)   # ... postpone key setup
751         st      $t1,240($key)
752         lghi    %r2,0
753         br      %r14
754
755 .align  16
756 .Lekey_internal:
757         stmg    %r6,%r13,48($sp)        # all volatile regs, but $ra!
758
759         bras    $tbl,1f
760 1:      aghi    $tbl,AES_Te+2048-.
761
762         llgf    $s0,0($inp)
763         llgf    $s1,4($inp)
764         llgf    $s2,8($inp)
765         llgf    $s3,12($inp)
766         st      $s0,0($key)
767         st      $s1,4($key)
768         st      $s2,8($key)
769         st      $s3,12($key)
770         lghi    $t1,128
771         cr      $bits,$t1
772         jne     .Lnot128
773
774         llill   $mask,0xff
775         lghi    $t3,0                   # i=0
776         lghi    $rounds,10
777         st      $t3,236($key)           # mark as set up
778         st      $rounds,240($key)
779
780 .align  8
781 .L128_loop:
782         llgfr   $t2,$s3                 # temp=rk[3]
783         srlg    $i1,$s3,8
784         srlg    $i2,$s3,16
785         srlg    $i3,$s3,24
786         nr      $t2,$mask
787         nr      $i1,$mask
788         nr      $i2,$mask
789         la      $t2,0($t2,$tbl)
790         la      $i1,0($i1,$tbl)
791         la      $i2,0($i2,$tbl)
792         la      $i3,0($i3,$tbl)
793         icm     $t2,2,0($t2)            # Te4[rk[3]>>0]<<8
794         icm     $t2,4,0($i1)            # Te4[rk[3]>>8]<<16
795         icm     $t2,8,0($i2)            # Te4[rk[3]>>16]<<24
796         icm     $t2,1,0($i3)            # Te4[rk[3]>>24]
797         x       $t2,256($t3,$tbl)       # rcon[i]
798         xr      $s0,$t2                 # rk[4]=rk[0]^...
799         xr      $s1,$s0                 # rk[5]=rk[1]^rk[4]
800         xr      $s2,$s1                 # rk[6]=rk[2]^rk[5]
801         xr      $s3,$s2                 # rk[7]=rk[3]^rk[6]
802         st      $s0,16($key)
803         st      $s1,20($key)
804         st      $s2,24($key)
805         st      $s3,28($key)
806         la      $key,16($key)           # key+=4
807         la      $t3,4($t3)              # i++
808         brct    $rounds,.L128_loop
809         lghi    %r2,0
810         lmg     %r6,%r13,48($sp)
811         br      $ra
812
813 .align  4
814 .Lnot128:
815         llgf    $t1,16($inp)
816         llgf    $t2,20($inp)
817         st      $t1,16($key)
818         st      $t2,20($key)
819         lghi    $t1,192
820         cr      $bits,$t1
821         jne     .Lnot192
822
823         llill   $mask,0xff
824         lghi    $t3,0                   # i=0
825         lghi    $rounds,12
826         st      $rounds,240($key)
827         lghi    $rounds,8
828
829 .align  8
830 .L192_loop:
831         srlg    $i1,$t2,8
832         srlg    $i2,$t2,16
833         srlg    $i3,$t2,24
834         nr      $t2,$mask
835         nr      $i1,$mask
836         nr      $i2,$mask
837         la      $t2,0($t2,$tbl)
838         la      $i1,0($i1,$tbl)
839         la      $i2,0($i2,$tbl)
840         la      $i3,0($i3,$tbl)
841         icm     $t2,2,0($t2)            # Te4[rk[5]>>0]<<8
842         icm     $t2,4,0($i1)            # Te4[rk[5]>>8]<<16
843         icm     $t2,8,0($i2)            # Te4[rk[5]>>16]<<24
844         icm     $t2,1,0($i3)            # Te4[rk[5]>>24]
845         x       $t2,256($t3,$tbl)       # rcon[i]
846         xr      $s0,$t2                 # rk[6]=rk[0]^...
847         xr      $s1,$s0                 # rk[7]=rk[1]^rk[6]
848         xr      $s2,$s1                 # rk[8]=rk[2]^rk[7]
849         xr      $s3,$s2                 # rk[9]=rk[3]^rk[8]
850         st      $s0,24($key)
851         st      $s1,28($key)
852         st      $s2,32($key)
853         st      $s3,36($key)
854         brct    $rounds,.L192_continue
855         lghi    %r2,0
856         lmg     %r6,%r13,48($sp)
857         br      $ra
858 .align  4
859 .L192_continue:
860         lgr     $t2,$s3
861         x       $t2,16($key)            # rk[10]=rk[4]^rk[9]
862         st      $t2,40($key)
863         x       $t2,20($key)            # rk[11]=rk[5]^rk[10]
864         st      $t2,44($key)
865         la      $key,24($key)           # key+=6
866         la      $t3,4($t3)              # i++
867         j       .L192_loop
868
869 .align  4
870 .Lnot192:
871         llgf    $t1,24($inp)
872         llgf    $t2,28($inp)
873         st      $t1,24($key)
874         st      $t2,28($key)
875         llill   $mask,0xff
876         lghi    $t3,0                   # i=0
877         lghi    $rounds,14
878         st      $rounds,240($key)
879         lghi    $rounds,7
880
881 .align  8
882 .L256_loop:
883         srlg    $i1,$t2,8
884         srlg    $i2,$t2,16
885         srlg    $i3,$t2,24
886         nr      $t2,$mask
887         nr      $i1,$mask
888         nr      $i2,$mask
889         la      $t2,0($t2,$tbl)
890         la      $i1,0($i1,$tbl)
891         la      $i2,0($i2,$tbl)
892         la      $i3,0($i3,$tbl)
893         icm     $t2,2,0($t2)            # Te4[rk[7]>>0]<<8
894         icm     $t2,4,0($i1)            # Te4[rk[7]>>8]<<16
895         icm     $t2,8,0($i2)            # Te4[rk[7]>>16]<<24
896         icm     $t2,1,0($i3)            # Te4[rk[7]>>24]
897         x       $t2,256($t3,$tbl)       # rcon[i]
898         xr      $s0,$t2                 # rk[8]=rk[0]^...
899         xr      $s1,$s0                 # rk[9]=rk[1]^rk[8]
900         xr      $s2,$s1                 # rk[10]=rk[2]^rk[9]
901         xr      $s3,$s2                 # rk[11]=rk[3]^rk[10]
902         st      $s0,32($key)
903         st      $s1,36($key)
904         st      $s2,40($key)
905         st      $s3,44($key)
906         brct    $rounds,.L256_continue
907         lghi    %r2,0
908         lmg     %r6,%r13,48($sp)
909         br      $ra
910 .align  4
911 .L256_continue:
912         lgr     $t2,$s3                 # temp=rk[11]
913         srlg    $i1,$s3,8
914         srlg    $i2,$s3,16
915         srlg    $i3,$s3,24
916         nr      $t2,$mask
917         nr      $i1,$mask
918         nr      $i2,$mask
919         la      $t2,0($t2,$tbl)
920         la      $i1,0($i1,$tbl)
921         la      $i2,0($i2,$tbl)
922         la      $i3,0($i3,$tbl)
923         icm     $t2,1,0($t2)            # Te4[rk[11]>>0]
924         icm     $t2,2,0($i1)            # Te4[rk[11]>>8]<<8
925         icm     $t2,4,0($i2)            # Te4[rk[11]>>16]<<16
926         icm     $t2,8,0($i3)            # Te4[rk[11]>>24]<<24
927         x       $t2,16($key)            # rk[12]=rk[4]^...
928         st      $t2,48($key)
929         x       $t2,20($key)            # rk[13]=rk[5]^rk[12]
930         st      $t2,52($key)
931         x       $t2,24($key)            # rk[14]=rk[6]^rk[13]
932         st      $t2,56($key)
933         x       $t2,28($key)            # rk[15]=rk[7]^rk[14]
934         st      $t2,60($key)
935
936         la      $key,32($key)           # key+=8
937         la      $t3,4($t3)              # i++
938         j       .L256_loop
939 .align  4
940 .Lminus1:
941         lghi    %r2,-1
942         br      %r14
943 .size   AES_set_encrypt_key,.-AES_set_encrypt_key
944
945 # void AES_set_decrypt_key(const unsigned char *in, int bits,
946 #                AES_KEY *key) {
947 .globl  AES_set_decrypt_key
948 .type   AES_set_decrypt_key,\@function
949 .align  16
950 AES_set_decrypt_key:
951         stg     $key,32($sp)            # I rely on AES_set_encrypt_key to
952         stg     $ra,112($sp)            # save [other] volatile registers!
953         bras    $ra,AES_set_encrypt_key
954         lg      $key,32($sp)
955         lg      $ra,112($sp)
956         ltgr    %r2,%r2
957         bnzr    $ra
958
959         lghi    $t1,10
960         c       $t1,240($key)
961         jne     .Lgo
962         lghi    $t1,0
963         c       $t1,236($key)
964         je      .Lgo
965
966         l       $t1,0($key)             # just copy 128 bits otherwise
967         l       $t2,4($key)
968         l       $t3,8($key)
969         l       $bits,12($key)
970         st      $t1,160($key)
971         st      $t2,164($key)
972         st      $t3,168($key)
973         st      $bits,172($key)
974         lghi    %r2,0
975         br      $ra
976
977 .align  16
978 .Ldkey_internal:
979         stg     $key,32($sp)
980         stg     $ra,40($sp)
981         bras    $ra,.Lekey_internal
982         lg      $key,32($sp)
983         lg      $ra,40($sp)
984
985 .Lgo:   llgf    $rounds,240($key)
986         lghi    $i1,0
987         sllg    $i2,$rounds,4
988         srl     $rounds,1
989
990 .align  8
991 .Linv:  l       $s0,0($i1,$key)
992         l       $s1,4($i1,$key)
993         l       $s2,8($i1,$key)
994         l       $s3,12($i1,$key)
995         l       $t1,0($i2,$key)
996         l       $t2,4($i2,$key)
997         l       $t3,8($i2,$key)
998         l       $i3,12($i2,$key)
999         st      $s0,0($i2,$key)
1000         st      $s1,4($i2,$key)
1001         st      $s2,8($i2,$key)
1002         st      $s3,12($i2,$key)
1003         st      $t1,0($i1,$key)
1004         st      $t2,4($i1,$key)
1005         st      $t3,8($i1,$key)
1006         st      $i3,12($i1,$key)
1007         aghi    $i1,16
1008         aghi    $i2,-16
1009         brct    $rounds,.Linv
1010 ___
1011 $mask80=$i1;
1012 $mask1b=$i2;
1013 $maskfe=$i3;
1014 $code.=<<___;
1015         llgf    $rounds,240($key)
1016         aghi    $rounds,-1
1017         sll     $rounds,2       # (rounds-1)*4
1018         llilh   $mask80,0x8080
1019         oill    $mask80,0x8080
1020         llilh   $mask1b,0x1b1b
1021         oill    $mask1b,0x1b1b
1022         llilh   $maskfe,0xfefe
1023         oill    $maskfe,0xfefe
1024
1025 .align  8
1026 .Lmix:  l       $s0,16($key)    # tp1
1027         lr      $s1,$s0
1028         ngr     $s1,$mask80
1029         srlg    $t1,$s1,7
1030         slr     $s1,$t1
1031         nr      $s1,$mask1b
1032         sllg    $t1,$s0,1
1033         nr      $t1,$maskfe
1034         xr      $s1,$t1         # tp2
1035
1036         lr      $s2,$s1
1037         ngr     $s2,$mask80
1038         srlg    $t1,$s2,7
1039         slr     $s2,$t1
1040         nr      $s2,$mask1b
1041         sllg    $t1,$s1,1
1042         nr      $t1,$maskfe
1043         xr      $s2,$t1         # tp4
1044
1045         lr      $s3,$s2
1046         ngr     $s3,$mask80
1047         srlg    $t1,$s3,7
1048         slr     $s3,$t1
1049         nr      $s3,$mask1b
1050         sllg    $t1,$s2,1
1051         nr      $t1,$maskfe
1052         xr      $s3,$t1         # tp8
1053
1054         xr      $s1,$s0         # tp2^tp1
1055         xr      $s2,$s0         # tp4^tp1
1056         rll     $s0,$s0,24      # = ROTATE(tp1,8)
1057         xr      $s0,$s1         # ^=tp2^tp1
1058         xr      $s0,$s2         # ^=tp4^tp1
1059         xr      $s0,$s3         # ^= tp8[^(tp4^tp1)^(tp2^tp1)=tp4^tp2]
1060         xr      $s1,$s3         # tp2^tp1^tp8
1061         rll     $s1,$s1,8
1062         xr      $s0,$s1         # ^= ROTATE(tp8^tp2^tp1,24)
1063         xr      $s2,$s3         # tp4^tp1^tp8
1064         rll     $s2,$s2,16
1065         xr      $s0,$s2         # ^= ROTATE(tp8^tp4^tp1,16)
1066         rll     $s3,$s3,24
1067         xr      $s0,$s3         # ^= ROTATE(tp8,8)
1068
1069         st      $s0,16($key)
1070         la      $key,4($key)
1071         brct    $rounds,.Lmix
1072
1073         lmg     %r6,%r13,48($sp)# this was saved by AES_set_encrypt_key!
1074         lghi    %r2,0
1075         br      $ra
1076 .size   AES_set_decrypt_key,.-AES_set_decrypt_key
1077 .string "AES for s390x, CRYPTOGAMS by <appro\@openssl.org>"
1078 ___
1079
1080 $code =~ s/\`([^\`]*)\`/eval $1/gem;
1081 print $code;