Add OpenSSL copyright to .pl files
[openssl.git] / crypto / aes / asm / aes-s390x.pl
1 #! /usr/bin/env perl
2 # Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved.
3 #
4 # Licensed under the OpenSSL license (the "License").  You may not use
5 # this file except in compliance with the License.  You can obtain a copy
6 # in the file LICENSE in the source distribution or at
7 # https://www.openssl.org/source/license.html
8
9
10 # ====================================================================
11 # Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
12 # project. The module is, however, dual licensed under OpenSSL and
13 # CRYPTOGAMS licenses depending on where you obtain it. For further
14 # details see http://www.openssl.org/~appro/cryptogams/.
15 # ====================================================================
16
17 # AES for s390x.
18
19 # April 2007.
20 #
21 # Software performance improvement over gcc-generated code is ~70% and
22 # in absolute terms is ~73 cycles per byte processed with 128-bit key.
23 # You're likely to exclaim "why so slow?" Keep in mind that z-CPUs are
24 # *strictly* in-order execution and issued instruction [in this case
25 # load value from memory is critical] has to complete before execution
26 # flow proceeds. S-boxes are compressed to 2KB[+256B].
27 #
28 # As for hardware acceleration support. It's basically a "teaser," as
29 # it can and should be improved in several ways. Most notably support
30 # for CBC is not utilized, nor multiple blocks are ever processed.
31 # Then software key schedule can be postponed till hardware support
32 # detection... Performance improvement over assembler is reportedly
33 # ~2.5x, but can reach >8x [naturally on larger chunks] if proper
34 # support is implemented.
35
36 # May 2007.
37 #
38 # Implement AES_set_[en|de]crypt_key. Key schedule setup is avoided
39 # for 128-bit keys, if hardware support is detected.
40
41 # Januray 2009.
42 #
43 # Add support for hardware AES192/256 and reschedule instructions to
44 # minimize/avoid Address Generation Interlock hazard and to favour
45 # dual-issue z10 pipeline. This gave ~25% improvement on z10 and
46 # almost 50% on z9. The gain is smaller on z10, because being dual-
47 # issue z10 makes it improssible to eliminate the interlock condition:
48 # critial path is not long enough. Yet it spends ~24 cycles per byte
49 # processed with 128-bit key.
50 #
51 # Unlike previous version hardware support detection takes place only
52 # at the moment of key schedule setup, which is denoted in key->rounds.
53 # This is done, because deferred key setup can't be made MT-safe, not
54 # for keys longer than 128 bits.
55 #
56 # Add AES_cbc_encrypt, which gives incredible performance improvement,
57 # it was measured to be ~6.6x. It's less than previously mentioned 8x,
58 # because software implementation was optimized.
59
60 # May 2010.
61 #
62 # Add AES_ctr32_encrypt. If hardware-assisted, it provides up to 4.3x
63 # performance improvement over "generic" counter mode routine relying
64 # on single-block, also hardware-assisted, AES_encrypt. "Up to" refers
65 # to the fact that exact throughput value depends on current stack
66 # frame alignment within 4KB page. In worst case you get ~75% of the
67 # maximum, but *on average* it would be as much as ~98%. Meaning that
68 # worst case is unlike, it's like hitting ravine on plateau.
69
70 # November 2010.
71 #
72 # Adapt for -m31 build. If kernel supports what's called "highgprs"
73 # feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit
74 # instructions and achieve "64-bit" performance even in 31-bit legacy
75 # application context. The feature is not specific to any particular
76 # processor, as long as it's "z-CPU". Latter implies that the code
77 # remains z/Architecture specific. On z990 it was measured to perform
78 # 2x better than code generated by gcc 4.3.
79
80 # December 2010.
81 #
82 # Add support for z196 "cipher message with counter" instruction.
83 # Note however that it's disengaged, because it was measured to
84 # perform ~12% worse than vanilla km-based code...
85
86 # February 2011.
87 #
88 # Add AES_xts_[en|de]crypt. This includes support for z196 km-xts-aes
89 # instructions, which deliver ~70% improvement at 8KB block size over
90 # vanilla km-based code, 37% - at most like 512-bytes block size.
91
92 $flavour = shift;
93
94 if ($flavour =~ /3[12]/) {
95         $SIZE_T=4;
96         $g="";
97 } else {
98         $SIZE_T=8;
99         $g="g";
100 }
101
102 while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
103 open STDOUT,">$output";
104
105 $softonly=0;    # allow hardware support
106
107 $t0="%r0";      $mask="%r0";
108 $t1="%r1";
109 $t2="%r2";      $inp="%r2";
110 $t3="%r3";      $out="%r3";     $bits="%r3";
111 $key="%r4";
112 $i1="%r5";
113 $i2="%r6";
114 $i3="%r7";
115 $s0="%r8";
116 $s1="%r9";
117 $s2="%r10";
118 $s3="%r11";
119 $tbl="%r12";
120 $rounds="%r13";
121 $ra="%r14";
122 $sp="%r15";
123
124 $stdframe=16*$SIZE_T+4*8;
125
126 sub _data_word()
127 { my $i;
128     while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; }
129 }
130
131 $code=<<___;
132 .text
133
134 .type   AES_Te,\@object
135 .align  256
136 AES_Te:
137 ___
138 &_data_word(
139         0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
140         0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
141         0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
142         0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
143         0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
144         0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
145         0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
146         0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
147         0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
148         0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
149         0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
150         0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
151         0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
152         0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
153         0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
154         0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
155         0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
156         0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
157         0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
158         0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
159         0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
160         0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
161         0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
162         0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
163         0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
164         0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
165         0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
166         0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
167         0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
168         0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
169         0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
170         0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
171         0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
172         0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
173         0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
174         0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
175         0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
176         0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
177         0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
178         0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
179         0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
180         0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
181         0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
182         0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
183         0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
184         0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
185         0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
186         0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
187         0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
188         0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
189         0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
190         0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
191         0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
192         0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
193         0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
194         0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
195         0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
196         0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
197         0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
198         0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
199         0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
200         0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
201         0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
202         0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a);
203 $code.=<<___;
204 # Te4[256]
205 .byte   0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
206 .byte   0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
207 .byte   0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
208 .byte   0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
209 .byte   0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
210 .byte   0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
211 .byte   0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
212 .byte   0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
213 .byte   0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
214 .byte   0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
215 .byte   0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
216 .byte   0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
217 .byte   0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
218 .byte   0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
219 .byte   0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
220 .byte   0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
221 .byte   0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
222 .byte   0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
223 .byte   0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
224 .byte   0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
225 .byte   0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
226 .byte   0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
227 .byte   0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
228 .byte   0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
229 .byte   0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
230 .byte   0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
231 .byte   0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
232 .byte   0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
233 .byte   0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
234 .byte   0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
235 .byte   0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
236 .byte   0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
237 # rcon[]
238 .long   0x01000000, 0x02000000, 0x04000000, 0x08000000
239 .long   0x10000000, 0x20000000, 0x40000000, 0x80000000
240 .long   0x1B000000, 0x36000000, 0, 0, 0, 0, 0, 0
241 .align  256
242 .size   AES_Te,.-AES_Te
243
244 # void AES_encrypt(const unsigned char *inp, unsigned char *out,
245 #                const AES_KEY *key) {
246 .globl  AES_encrypt
247 .type   AES_encrypt,\@function
248 AES_encrypt:
249 ___
250 $code.=<<___ if (!$softonly);
251         l       %r0,240($key)
252         lhi     %r1,16
253         clr     %r0,%r1
254         jl      .Lesoft
255
256         la      %r1,0($key)
257         #la     %r2,0($inp)
258         la      %r4,0($out)
259         lghi    %r3,16          # single block length
260         .long   0xb92e0042      # km %r4,%r2
261         brc     1,.-4           # can this happen?
262         br      %r14
263 .align  64
264 .Lesoft:
265 ___
266 $code.=<<___;
267         stm${g} %r3,$ra,3*$SIZE_T($sp)
268
269         llgf    $s0,0($inp)
270         llgf    $s1,4($inp)
271         llgf    $s2,8($inp)
272         llgf    $s3,12($inp)
273
274         larl    $tbl,AES_Te
275         bras    $ra,_s390x_AES_encrypt
276
277         l${g}   $out,3*$SIZE_T($sp)
278         st      $s0,0($out)
279         st      $s1,4($out)
280         st      $s2,8($out)
281         st      $s3,12($out)
282
283         lm${g}  %r6,$ra,6*$SIZE_T($sp)
284         br      $ra
285 .size   AES_encrypt,.-AES_encrypt
286
287 .type   _s390x_AES_encrypt,\@function
288 .align  16
289 _s390x_AES_encrypt:
290         st${g}  $ra,15*$SIZE_T($sp)
291         x       $s0,0($key)
292         x       $s1,4($key)
293         x       $s2,8($key)
294         x       $s3,12($key)
295         l       $rounds,240($key)
296         llill   $mask,`0xff<<3`
297         aghi    $rounds,-1
298         j       .Lenc_loop
299 .align  16
300 .Lenc_loop:
301         sllg    $t1,$s0,`0+3`
302         srlg    $t2,$s0,`8-3`
303         srlg    $t3,$s0,`16-3`
304         srl     $s0,`24-3`
305         nr      $s0,$mask
306         ngr     $t1,$mask
307         nr      $t2,$mask
308         nr      $t3,$mask
309
310         srlg    $i1,$s1,`16-3`  # i0
311         sllg    $i2,$s1,`0+3`
312         srlg    $i3,$s1,`8-3`
313         srl     $s1,`24-3`
314         nr      $i1,$mask
315         nr      $s1,$mask
316         ngr     $i2,$mask
317         nr      $i3,$mask
318
319         l       $s0,0($s0,$tbl) # Te0[s0>>24]
320         l       $t1,1($t1,$tbl) # Te3[s0>>0]
321         l       $t2,2($t2,$tbl) # Te2[s0>>8]
322         l       $t3,3($t3,$tbl) # Te1[s0>>16]
323
324         x       $s0,3($i1,$tbl) # Te1[s1>>16]
325         l       $s1,0($s1,$tbl) # Te0[s1>>24]
326         x       $t2,1($i2,$tbl) # Te3[s1>>0]
327         x       $t3,2($i3,$tbl) # Te2[s1>>8]
328
329         srlg    $i1,$s2,`8-3`   # i0
330         srlg    $i2,$s2,`16-3`  # i1
331         nr      $i1,$mask
332         nr      $i2,$mask
333         sllg    $i3,$s2,`0+3`
334         srl     $s2,`24-3`
335         nr      $s2,$mask
336         ngr     $i3,$mask
337
338         xr      $s1,$t1
339         srlg    $ra,$s3,`8-3`   # i1
340         sllg    $t1,$s3,`0+3`   # i0
341         nr      $ra,$mask
342         la      $key,16($key)
343         ngr     $t1,$mask
344
345         x       $s0,2($i1,$tbl) # Te2[s2>>8]
346         x       $s1,3($i2,$tbl) # Te1[s2>>16]
347         l       $s2,0($s2,$tbl) # Te0[s2>>24]
348         x       $t3,1($i3,$tbl) # Te3[s2>>0]
349
350         srlg    $i3,$s3,`16-3`  # i2
351         xr      $s2,$t2
352         srl     $s3,`24-3`
353         nr      $i3,$mask
354         nr      $s3,$mask
355
356         x       $s0,0($key)
357         x       $s1,4($key)
358         x       $s2,8($key)
359         x       $t3,12($key)
360
361         x       $s0,1($t1,$tbl) # Te3[s3>>0]
362         x       $s1,2($ra,$tbl) # Te2[s3>>8]
363         x       $s2,3($i3,$tbl) # Te1[s3>>16]
364         l       $s3,0($s3,$tbl) # Te0[s3>>24]
365         xr      $s3,$t3
366
367         brct    $rounds,.Lenc_loop
368         .align  16
369
370         sllg    $t1,$s0,`0+3`
371         srlg    $t2,$s0,`8-3`
372         ngr     $t1,$mask
373         srlg    $t3,$s0,`16-3`
374         srl     $s0,`24-3`
375         nr      $s0,$mask
376         nr      $t2,$mask
377         nr      $t3,$mask
378
379         srlg    $i1,$s1,`16-3`  # i0
380         sllg    $i2,$s1,`0+3`
381         ngr     $i2,$mask
382         srlg    $i3,$s1,`8-3`
383         srl     $s1,`24-3`
384         nr      $i1,$mask
385         nr      $s1,$mask
386         nr      $i3,$mask
387
388         llgc    $s0,2($s0,$tbl) # Te4[s0>>24]
389         llgc    $t1,2($t1,$tbl) # Te4[s0>>0]
390         sll     $s0,24
391         llgc    $t2,2($t2,$tbl) # Te4[s0>>8]
392         llgc    $t3,2($t3,$tbl) # Te4[s0>>16]
393         sll     $t2,8
394         sll     $t3,16
395
396         llgc    $i1,2($i1,$tbl) # Te4[s1>>16]
397         llgc    $s1,2($s1,$tbl) # Te4[s1>>24]
398         llgc    $i2,2($i2,$tbl) # Te4[s1>>0]
399         llgc    $i3,2($i3,$tbl) # Te4[s1>>8]
400         sll     $i1,16
401         sll     $s1,24
402         sll     $i3,8
403         or      $s0,$i1
404         or      $s1,$t1
405         or      $t2,$i2
406         or      $t3,$i3
407         
408         srlg    $i1,$s2,`8-3`   # i0
409         srlg    $i2,$s2,`16-3`  # i1
410         nr      $i1,$mask
411         nr      $i2,$mask
412         sllg    $i3,$s2,`0+3`
413         srl     $s2,`24-3`
414         ngr     $i3,$mask
415         nr      $s2,$mask
416
417         sllg    $t1,$s3,`0+3`   # i0
418         srlg    $ra,$s3,`8-3`   # i1
419         ngr     $t1,$mask
420
421         llgc    $i1,2($i1,$tbl) # Te4[s2>>8]
422         llgc    $i2,2($i2,$tbl) # Te4[s2>>16]
423         sll     $i1,8
424         llgc    $s2,2($s2,$tbl) # Te4[s2>>24]
425         llgc    $i3,2($i3,$tbl) # Te4[s2>>0]
426         sll     $i2,16
427         nr      $ra,$mask
428         sll     $s2,24
429         or      $s0,$i1
430         or      $s1,$i2
431         or      $s2,$t2
432         or      $t3,$i3
433
434         srlg    $i3,$s3,`16-3`  # i2
435         srl     $s3,`24-3`
436         nr      $i3,$mask
437         nr      $s3,$mask
438
439         l       $t0,16($key)
440         l       $t2,20($key)
441
442         llgc    $i1,2($t1,$tbl) # Te4[s3>>0]
443         llgc    $i2,2($ra,$tbl) # Te4[s3>>8]
444         llgc    $i3,2($i3,$tbl) # Te4[s3>>16]
445         llgc    $s3,2($s3,$tbl) # Te4[s3>>24]
446         sll     $i2,8
447         sll     $i3,16
448         sll     $s3,24
449         or      $s0,$i1
450         or      $s1,$i2
451         or      $s2,$i3
452         or      $s3,$t3
453
454         l${g}   $ra,15*$SIZE_T($sp)
455         xr      $s0,$t0
456         xr      $s1,$t2
457         x       $s2,24($key)
458         x       $s3,28($key)
459
460         br      $ra     
461 .size   _s390x_AES_encrypt,.-_s390x_AES_encrypt
462 ___
463
464 $code.=<<___;
465 .type   AES_Td,\@object
466 .align  256
467 AES_Td:
468 ___
469 &_data_word(
470         0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
471         0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
472         0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
473         0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
474         0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
475         0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
476         0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
477         0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
478         0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
479         0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
480         0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
481         0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
482         0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
483         0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
484         0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
485         0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
486         0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
487         0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
488         0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
489         0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
490         0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
491         0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
492         0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
493         0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
494         0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
495         0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
496         0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
497         0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
498         0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
499         0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
500         0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
501         0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
502         0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
503         0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
504         0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
505         0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
506         0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
507         0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
508         0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
509         0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
510         0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
511         0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
512         0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
513         0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
514         0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
515         0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
516         0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
517         0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
518         0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
519         0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
520         0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
521         0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
522         0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
523         0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
524         0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
525         0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
526         0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
527         0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
528         0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
529         0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
530         0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
531         0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
532         0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
533         0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742);
534 $code.=<<___;
535 # Td4[256]
536 .byte   0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
537 .byte   0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
538 .byte   0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
539 .byte   0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
540 .byte   0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
541 .byte   0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
542 .byte   0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
543 .byte   0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
544 .byte   0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
545 .byte   0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
546 .byte   0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
547 .byte   0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
548 .byte   0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
549 .byte   0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
550 .byte   0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
551 .byte   0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
552 .byte   0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
553 .byte   0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
554 .byte   0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
555 .byte   0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
556 .byte   0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
557 .byte   0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
558 .byte   0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
559 .byte   0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
560 .byte   0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
561 .byte   0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
562 .byte   0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
563 .byte   0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
564 .byte   0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
565 .byte   0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
566 .byte   0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
567 .byte   0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
568 .size   AES_Td,.-AES_Td
569
570 # void AES_decrypt(const unsigned char *inp, unsigned char *out,
571 #                const AES_KEY *key) {
572 .globl  AES_decrypt
573 .type   AES_decrypt,\@function
574 AES_decrypt:
575 ___
576 $code.=<<___ if (!$softonly);
577         l       %r0,240($key)
578         lhi     %r1,16
579         clr     %r0,%r1
580         jl      .Ldsoft
581
582         la      %r1,0($key)
583         #la     %r2,0($inp)
584         la      %r4,0($out)
585         lghi    %r3,16          # single block length
586         .long   0xb92e0042      # km %r4,%r2
587         brc     1,.-4           # can this happen?
588         br      %r14
589 .align  64
590 .Ldsoft:
591 ___
592 $code.=<<___;
593         stm${g} %r3,$ra,3*$SIZE_T($sp)
594
595         llgf    $s0,0($inp)
596         llgf    $s1,4($inp)
597         llgf    $s2,8($inp)
598         llgf    $s3,12($inp)
599
600         larl    $tbl,AES_Td
601         bras    $ra,_s390x_AES_decrypt
602
603         l${g}   $out,3*$SIZE_T($sp)
604         st      $s0,0($out)
605         st      $s1,4($out)
606         st      $s2,8($out)
607         st      $s3,12($out)
608
609         lm${g}  %r6,$ra,6*$SIZE_T($sp)
610         br      $ra
611 .size   AES_decrypt,.-AES_decrypt
612
613 .type   _s390x_AES_decrypt,\@function
614 .align  16
615 _s390x_AES_decrypt:
616         st${g}  $ra,15*$SIZE_T($sp)
617         x       $s0,0($key)
618         x       $s1,4($key)
619         x       $s2,8($key)
620         x       $s3,12($key)
621         l       $rounds,240($key)
622         llill   $mask,`0xff<<3`
623         aghi    $rounds,-1
624         j       .Ldec_loop
625 .align  16
626 .Ldec_loop:
627         srlg    $t1,$s0,`16-3`
628         srlg    $t2,$s0,`8-3`
629         sllg    $t3,$s0,`0+3`
630         srl     $s0,`24-3`
631         nr      $s0,$mask
632         nr      $t1,$mask
633         nr      $t2,$mask
634         ngr     $t3,$mask
635
636         sllg    $i1,$s1,`0+3`   # i0
637         srlg    $i2,$s1,`16-3`
638         srlg    $i3,$s1,`8-3`
639         srl     $s1,`24-3`
640         ngr     $i1,$mask
641         nr      $s1,$mask
642         nr      $i2,$mask
643         nr      $i3,$mask
644
645         l       $s0,0($s0,$tbl) # Td0[s0>>24]
646         l       $t1,3($t1,$tbl) # Td1[s0>>16]
647         l       $t2,2($t2,$tbl) # Td2[s0>>8]
648         l       $t3,1($t3,$tbl) # Td3[s0>>0]
649
650         x       $s0,1($i1,$tbl) # Td3[s1>>0]
651         l       $s1,0($s1,$tbl) # Td0[s1>>24]
652         x       $t2,3($i2,$tbl) # Td1[s1>>16]
653         x       $t3,2($i3,$tbl) # Td2[s1>>8]
654
655         srlg    $i1,$s2,`8-3`   # i0
656         sllg    $i2,$s2,`0+3`   # i1
657         srlg    $i3,$s2,`16-3`
658         srl     $s2,`24-3`
659         nr      $i1,$mask
660         ngr     $i2,$mask
661         nr      $s2,$mask
662         nr      $i3,$mask
663
664         xr      $s1,$t1
665         srlg    $ra,$s3,`8-3`   # i1
666         srlg    $t1,$s3,`16-3`  # i0
667         nr      $ra,$mask
668         la      $key,16($key)
669         nr      $t1,$mask
670
671         x       $s0,2($i1,$tbl) # Td2[s2>>8]
672         x       $s1,1($i2,$tbl) # Td3[s2>>0]
673         l       $s2,0($s2,$tbl) # Td0[s2>>24]
674         x       $t3,3($i3,$tbl) # Td1[s2>>16]
675
676         sllg    $i3,$s3,`0+3`   # i2
677         srl     $s3,`24-3`
678         ngr     $i3,$mask
679         nr      $s3,$mask
680
681         xr      $s2,$t2
682         x       $s0,0($key)
683         x       $s1,4($key)
684         x       $s2,8($key)
685         x       $t3,12($key)
686
687         x       $s0,3($t1,$tbl) # Td1[s3>>16]
688         x       $s1,2($ra,$tbl) # Td2[s3>>8]
689         x       $s2,1($i3,$tbl) # Td3[s3>>0]
690         l       $s3,0($s3,$tbl) # Td0[s3>>24]
691         xr      $s3,$t3
692
693         brct    $rounds,.Ldec_loop
694         .align  16
695
696         l       $t1,`2048+0`($tbl)      # prefetch Td4
697         l       $t2,`2048+64`($tbl)
698         l       $t3,`2048+128`($tbl)
699         l       $i1,`2048+192`($tbl)
700         llill   $mask,0xff
701
702         srlg    $i3,$s0,24      # i0
703         srlg    $t1,$s0,16
704         srlg    $t2,$s0,8
705         nr      $s0,$mask       # i3
706         nr      $t1,$mask
707
708         srlg    $i1,$s1,24
709         nr      $t2,$mask
710         srlg    $i2,$s1,16
711         srlg    $ra,$s1,8
712         nr      $s1,$mask       # i0
713         nr      $i2,$mask
714         nr      $ra,$mask
715
716         llgc    $i3,2048($i3,$tbl)      # Td4[s0>>24]
717         llgc    $t1,2048($t1,$tbl)      # Td4[s0>>16]
718         llgc    $t2,2048($t2,$tbl)      # Td4[s0>>8]
719         sll     $t1,16
720         llgc    $t3,2048($s0,$tbl)      # Td4[s0>>0]
721         sllg    $s0,$i3,24
722         sll     $t2,8
723
724         llgc    $s1,2048($s1,$tbl)      # Td4[s1>>0]
725         llgc    $i1,2048($i1,$tbl)      # Td4[s1>>24]
726         llgc    $i2,2048($i2,$tbl)      # Td4[s1>>16]
727         sll     $i1,24
728         llgc    $i3,2048($ra,$tbl)      # Td4[s1>>8]
729         sll     $i2,16
730         sll     $i3,8
731         or      $s0,$s1
732         or      $t1,$i1
733         or      $t2,$i2
734         or      $t3,$i3
735
736         srlg    $i1,$s2,8       # i0
737         srlg    $i2,$s2,24
738         srlg    $i3,$s2,16
739         nr      $s2,$mask       # i1
740         nr      $i1,$mask
741         nr      $i3,$mask
742         llgc    $i1,2048($i1,$tbl)      # Td4[s2>>8]
743         llgc    $s1,2048($s2,$tbl)      # Td4[s2>>0]
744         llgc    $i2,2048($i2,$tbl)      # Td4[s2>>24]
745         llgc    $i3,2048($i3,$tbl)      # Td4[s2>>16]
746         sll     $i1,8
747         sll     $i2,24
748         or      $s0,$i1
749         sll     $i3,16
750         or      $t2,$i2
751         or      $t3,$i3
752
753         srlg    $i1,$s3,16      # i0
754         srlg    $i2,$s3,8       # i1
755         srlg    $i3,$s3,24
756         nr      $s3,$mask       # i2
757         nr      $i1,$mask
758         nr      $i2,$mask
759
760         l${g}   $ra,15*$SIZE_T($sp)
761         or      $s1,$t1
762         l       $t0,16($key)
763         l       $t1,20($key)
764
765         llgc    $i1,2048($i1,$tbl)      # Td4[s3>>16]
766         llgc    $i2,2048($i2,$tbl)      # Td4[s3>>8]
767         sll     $i1,16
768         llgc    $s2,2048($s3,$tbl)      # Td4[s3>>0]
769         llgc    $s3,2048($i3,$tbl)      # Td4[s3>>24]
770         sll     $i2,8
771         sll     $s3,24
772         or      $s0,$i1
773         or      $s1,$i2
774         or      $s2,$t2
775         or      $s3,$t3
776
777         xr      $s0,$t0
778         xr      $s1,$t1
779         x       $s2,24($key)
780         x       $s3,28($key)
781
782         br      $ra     
783 .size   _s390x_AES_decrypt,.-_s390x_AES_decrypt
784 ___
785
786 $code.=<<___;
787 # void AES_set_encrypt_key(const unsigned char *in, int bits,
788 #                AES_KEY *key) {
789 .globl  AES_set_encrypt_key
790 .type   AES_set_encrypt_key,\@function
791 .align  16
792 AES_set_encrypt_key:
793 _s390x_AES_set_encrypt_key:
794         lghi    $t0,0
795         cl${g}r $inp,$t0
796         je      .Lminus1
797         cl${g}r $key,$t0
798         je      .Lminus1
799
800         lghi    $t0,128
801         clr     $bits,$t0
802         je      .Lproceed
803         lghi    $t0,192
804         clr     $bits,$t0
805         je      .Lproceed
806         lghi    $t0,256
807         clr     $bits,$t0
808         je      .Lproceed
809         lghi    %r2,-2
810         br      %r14
811
812 .align  16
813 .Lproceed:
814 ___
815 $code.=<<___ if (!$softonly);
816         # convert bits to km code, [128,192,256]->[18,19,20]
817         lhi     %r5,-128
818         lhi     %r0,18
819         ar      %r5,$bits
820         srl     %r5,6
821         ar      %r5,%r0
822
823         larl    %r1,OPENSSL_s390xcap_P
824         lg      %r0,0(%r1)
825         tmhl    %r0,0x4000      # check for message-security assist
826         jz      .Lekey_internal
827
828         llihh   %r0,0x8000
829         srlg    %r0,%r0,0(%r5)
830         ng      %r0,48(%r1)     # check kmc capability vector
831         jz      .Lekey_internal
832
833         lmg     %r0,%r1,0($inp) # just copy 128 bits...
834         stmg    %r0,%r1,0($key)
835         lhi     %r0,192
836         cr      $bits,%r0
837         jl      1f
838         lg      %r1,16($inp)
839         stg     %r1,16($key)
840         je      1f
841         lg      %r1,24($inp)
842         stg     %r1,24($key)
843 1:      st      $bits,236($key) # save bits [for debugging purposes]
844         lgr     $t0,%r5
845         st      %r5,240($key)   # save km code
846         lghi    %r2,0
847         br      %r14
848 ___
849 $code.=<<___;
850 .align  16
851 .Lekey_internal:
852         stm${g} %r4,%r13,4*$SIZE_T($sp) # all non-volatile regs and $key
853
854         larl    $tbl,AES_Te+2048
855
856         llgf    $s0,0($inp)
857         llgf    $s1,4($inp)
858         llgf    $s2,8($inp)
859         llgf    $s3,12($inp)
860         st      $s0,0($key)
861         st      $s1,4($key)
862         st      $s2,8($key)
863         st      $s3,12($key)
864         lghi    $t0,128
865         cr      $bits,$t0
866         jne     .Lnot128
867
868         llill   $mask,0xff
869         lghi    $t3,0                   # i=0
870         lghi    $rounds,10
871         st      $rounds,240($key)
872
873         llgfr   $t2,$s3                 # temp=rk[3]
874         srlg    $i1,$s3,8
875         srlg    $i2,$s3,16
876         srlg    $i3,$s3,24
877         nr      $t2,$mask
878         nr      $i1,$mask
879         nr      $i2,$mask
880
881 .align  16
882 .L128_loop:
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[3]>>0]<<8
888         icm     $t2,4,0($i1)            # Te4[rk[3]>>8]<<16
889         icm     $t2,8,0($i2)            # Te4[rk[3]>>16]<<24
890         icm     $t2,1,0($i3)            # Te4[rk[3]>>24]
891         x       $t2,256($t3,$tbl)       # rcon[i]
892         xr      $s0,$t2                 # rk[4]=rk[0]^...
893         xr      $s1,$s0                 # rk[5]=rk[1]^rk[4]
894         xr      $s2,$s1                 # rk[6]=rk[2]^rk[5]
895         xr      $s3,$s2                 # rk[7]=rk[3]^rk[6]
896
897         llgfr   $t2,$s3                 # temp=rk[3]
898         srlg    $i1,$s3,8
899         srlg    $i2,$s3,16
900         nr      $t2,$mask
901         nr      $i1,$mask
902         srlg    $i3,$s3,24
903         nr      $i2,$mask
904
905         st      $s0,16($key)
906         st      $s1,20($key)
907         st      $s2,24($key)
908         st      $s3,28($key)
909         la      $key,16($key)           # key+=4
910         la      $t3,4($t3)              # i++
911         brct    $rounds,.L128_loop
912         lghi    $t0,10
913         lghi    %r2,0
914         lm${g}  %r4,%r13,4*$SIZE_T($sp)
915         br      $ra
916
917 .align  16
918 .Lnot128:
919         llgf    $t0,16($inp)
920         llgf    $t1,20($inp)
921         st      $t0,16($key)
922         st      $t1,20($key)
923         lghi    $t0,192
924         cr      $bits,$t0
925         jne     .Lnot192
926
927         llill   $mask,0xff
928         lghi    $t3,0                   # i=0
929         lghi    $rounds,12
930         st      $rounds,240($key)
931         lghi    $rounds,8
932
933         srlg    $i1,$t1,8
934         srlg    $i2,$t1,16
935         srlg    $i3,$t1,24
936         nr      $t1,$mask
937         nr      $i1,$mask
938         nr      $i2,$mask
939
940 .align  16
941 .L192_loop:
942         la      $t1,0($t1,$tbl)
943         la      $i1,0($i1,$tbl)
944         la      $i2,0($i2,$tbl)
945         la      $i3,0($i3,$tbl)
946         icm     $t1,2,0($t1)            # Te4[rk[5]>>0]<<8
947         icm     $t1,4,0($i1)            # Te4[rk[5]>>8]<<16
948         icm     $t1,8,0($i2)            # Te4[rk[5]>>16]<<24
949         icm     $t1,1,0($i3)            # Te4[rk[5]>>24]
950         x       $t1,256($t3,$tbl)       # rcon[i]
951         xr      $s0,$t1                 # rk[6]=rk[0]^...
952         xr      $s1,$s0                 # rk[7]=rk[1]^rk[6]
953         xr      $s2,$s1                 # rk[8]=rk[2]^rk[7]
954         xr      $s3,$s2                 # rk[9]=rk[3]^rk[8]
955
956         st      $s0,24($key)
957         st      $s1,28($key)
958         st      $s2,32($key)
959         st      $s3,36($key)
960         brct    $rounds,.L192_continue
961         lghi    $t0,12
962         lghi    %r2,0
963         lm${g}  %r4,%r13,4*$SIZE_T($sp)
964         br      $ra
965
966 .align  16
967 .L192_continue:
968         lgr     $t1,$s3
969         x       $t1,16($key)            # rk[10]=rk[4]^rk[9]
970         st      $t1,40($key)
971         x       $t1,20($key)            # rk[11]=rk[5]^rk[10]
972         st      $t1,44($key)
973
974         srlg    $i1,$t1,8
975         srlg    $i2,$t1,16
976         srlg    $i3,$t1,24
977         nr      $t1,$mask
978         nr      $i1,$mask
979         nr      $i2,$mask
980
981         la      $key,24($key)           # key+=6
982         la      $t3,4($t3)              # i++
983         j       .L192_loop
984
985 .align  16
986 .Lnot192:
987         llgf    $t0,24($inp)
988         llgf    $t1,28($inp)
989         st      $t0,24($key)
990         st      $t1,28($key)
991         llill   $mask,0xff
992         lghi    $t3,0                   # i=0
993         lghi    $rounds,14
994         st      $rounds,240($key)
995         lghi    $rounds,7
996
997         srlg    $i1,$t1,8
998         srlg    $i2,$t1,16
999         srlg    $i3,$t1,24
1000         nr      $t1,$mask
1001         nr      $i1,$mask
1002         nr      $i2,$mask
1003
1004 .align  16
1005 .L256_loop:
1006         la      $t1,0($t1,$tbl)
1007         la      $i1,0($i1,$tbl)
1008         la      $i2,0($i2,$tbl)
1009         la      $i3,0($i3,$tbl)
1010         icm     $t1,2,0($t1)            # Te4[rk[7]>>0]<<8
1011         icm     $t1,4,0($i1)            # Te4[rk[7]>>8]<<16
1012         icm     $t1,8,0($i2)            # Te4[rk[7]>>16]<<24
1013         icm     $t1,1,0($i3)            # Te4[rk[7]>>24]
1014         x       $t1,256($t3,$tbl)       # rcon[i]
1015         xr      $s0,$t1                 # rk[8]=rk[0]^...
1016         xr      $s1,$s0                 # rk[9]=rk[1]^rk[8]
1017         xr      $s2,$s1                 # rk[10]=rk[2]^rk[9]
1018         xr      $s3,$s2                 # rk[11]=rk[3]^rk[10]
1019         st      $s0,32($key)
1020         st      $s1,36($key)
1021         st      $s2,40($key)
1022         st      $s3,44($key)
1023         brct    $rounds,.L256_continue
1024         lghi    $t0,14
1025         lghi    %r2,0
1026         lm${g}  %r4,%r13,4*$SIZE_T($sp)
1027         br      $ra
1028
1029 .align  16
1030 .L256_continue:
1031         lgr     $t1,$s3                 # temp=rk[11]
1032         srlg    $i1,$s3,8
1033         srlg    $i2,$s3,16
1034         srlg    $i3,$s3,24
1035         nr      $t1,$mask
1036         nr      $i1,$mask
1037         nr      $i2,$mask
1038         la      $t1,0($t1,$tbl)
1039         la      $i1,0($i1,$tbl)
1040         la      $i2,0($i2,$tbl)
1041         la      $i3,0($i3,$tbl)
1042         llgc    $t1,0($t1)              # Te4[rk[11]>>0]
1043         icm     $t1,2,0($i1)            # Te4[rk[11]>>8]<<8
1044         icm     $t1,4,0($i2)            # Te4[rk[11]>>16]<<16
1045         icm     $t1,8,0($i3)            # Te4[rk[11]>>24]<<24
1046         x       $t1,16($key)            # rk[12]=rk[4]^...
1047         st      $t1,48($key)
1048         x       $t1,20($key)            # rk[13]=rk[5]^rk[12]
1049         st      $t1,52($key)
1050         x       $t1,24($key)            # rk[14]=rk[6]^rk[13]
1051         st      $t1,56($key)
1052         x       $t1,28($key)            # rk[15]=rk[7]^rk[14]
1053         st      $t1,60($key)
1054
1055         srlg    $i1,$t1,8
1056         srlg    $i2,$t1,16
1057         srlg    $i3,$t1,24
1058         nr      $t1,$mask
1059         nr      $i1,$mask
1060         nr      $i2,$mask
1061
1062         la      $key,32($key)           # key+=8
1063         la      $t3,4($t3)              # i++
1064         j       .L256_loop
1065
1066 .Lminus1:
1067         lghi    %r2,-1
1068         br      $ra
1069 .size   AES_set_encrypt_key,.-AES_set_encrypt_key
1070
1071 # void AES_set_decrypt_key(const unsigned char *in, int bits,
1072 #                AES_KEY *key) {
1073 .globl  AES_set_decrypt_key
1074 .type   AES_set_decrypt_key,\@function
1075 .align  16
1076 AES_set_decrypt_key:
1077         #st${g} $key,4*$SIZE_T($sp)     # I rely on AES_set_encrypt_key to
1078         st${g}  $ra,14*$SIZE_T($sp)     # save non-volatile registers and $key!
1079         bras    $ra,_s390x_AES_set_encrypt_key
1080         #l${g}  $key,4*$SIZE_T($sp)
1081         l${g}   $ra,14*$SIZE_T($sp)
1082         ltgr    %r2,%r2
1083         bnzr    $ra
1084 ___
1085 $code.=<<___ if (!$softonly);
1086         #l      $t0,240($key)
1087         lhi     $t1,16
1088         cr      $t0,$t1
1089         jl      .Lgo
1090         oill    $t0,0x80        # set "decrypt" bit
1091         st      $t0,240($key)
1092         br      $ra
1093 ___
1094 $code.=<<___;
1095 .align  16
1096 .Lgo:   lgr     $rounds,$t0     #llgf   $rounds,240($key)
1097         la      $i1,0($key)
1098         sllg    $i2,$rounds,4
1099         la      $i2,0($i2,$key)
1100         srl     $rounds,1
1101         lghi    $t1,-16
1102
1103 .align  16
1104 .Linv:  lmg     $s0,$s1,0($i1)
1105         lmg     $s2,$s3,0($i2)
1106         stmg    $s0,$s1,0($i2)
1107         stmg    $s2,$s3,0($i1)
1108         la      $i1,16($i1)
1109         la      $i2,0($t1,$i2)
1110         brct    $rounds,.Linv
1111 ___
1112 $mask80=$i1;
1113 $mask1b=$i2;
1114 $maskfe=$i3;
1115 $code.=<<___;
1116         llgf    $rounds,240($key)
1117         aghi    $rounds,-1
1118         sll     $rounds,2       # (rounds-1)*4
1119         llilh   $mask80,0x8080
1120         llilh   $mask1b,0x1b1b
1121         llilh   $maskfe,0xfefe
1122         oill    $mask80,0x8080
1123         oill    $mask1b,0x1b1b
1124         oill    $maskfe,0xfefe
1125
1126 .align  16
1127 .Lmix:  l       $s0,16($key)    # tp1
1128         lr      $s1,$s0
1129         ngr     $s1,$mask80
1130         srlg    $t1,$s1,7
1131         slr     $s1,$t1
1132         nr      $s1,$mask1b
1133         sllg    $t1,$s0,1
1134         nr      $t1,$maskfe
1135         xr      $s1,$t1         # tp2
1136
1137         lr      $s2,$s1
1138         ngr     $s2,$mask80
1139         srlg    $t1,$s2,7
1140         slr     $s2,$t1
1141         nr      $s2,$mask1b
1142         sllg    $t1,$s1,1
1143         nr      $t1,$maskfe
1144         xr      $s2,$t1         # tp4
1145
1146         lr      $s3,$s2
1147         ngr     $s3,$mask80
1148         srlg    $t1,$s3,7
1149         slr     $s3,$t1
1150         nr      $s3,$mask1b
1151         sllg    $t1,$s2,1
1152         nr      $t1,$maskfe
1153         xr      $s3,$t1         # tp8
1154
1155         xr      $s1,$s0         # tp2^tp1
1156         xr      $s2,$s0         # tp4^tp1
1157         rll     $s0,$s0,24      # = ROTATE(tp1,8)
1158         xr      $s2,$s3         # ^=tp8
1159         xr      $s0,$s1         # ^=tp2^tp1
1160         xr      $s1,$s3         # tp2^tp1^tp8
1161         xr      $s0,$s2         # ^=tp4^tp1^tp8
1162         rll     $s1,$s1,8
1163         rll     $s2,$s2,16
1164         xr      $s0,$s1         # ^= ROTATE(tp8^tp2^tp1,24)
1165         rll     $s3,$s3,24
1166         xr      $s0,$s2         # ^= ROTATE(tp8^tp4^tp1,16)
1167         xr      $s0,$s3         # ^= ROTATE(tp8,8)
1168
1169         st      $s0,16($key)
1170         la      $key,4($key)
1171         brct    $rounds,.Lmix
1172
1173         lm${g}  %r6,%r13,6*$SIZE_T($sp)# as was saved by AES_set_encrypt_key!
1174         lghi    %r2,0
1175         br      $ra
1176 .size   AES_set_decrypt_key,.-AES_set_decrypt_key
1177 ___
1178
1179 ########################################################################
1180 # void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
1181 #                     size_t length, const AES_KEY *key,
1182 #                     unsigned char *ivec, const int enc)
1183 {
1184 my $inp="%r2";
1185 my $out="%r4";  # length and out are swapped
1186 my $len="%r3";
1187 my $key="%r5";
1188 my $ivp="%r6";
1189
1190 $code.=<<___;
1191 .globl  AES_cbc_encrypt
1192 .type   AES_cbc_encrypt,\@function
1193 .align  16
1194 AES_cbc_encrypt:
1195         xgr     %r3,%r4         # flip %r3 and %r4, out and len
1196         xgr     %r4,%r3
1197         xgr     %r3,%r4
1198 ___
1199 $code.=<<___ if (!$softonly);
1200         lhi     %r0,16
1201         cl      %r0,240($key)
1202         jh      .Lcbc_software
1203
1204         lg      %r0,0($ivp)     # copy ivec
1205         lg      %r1,8($ivp)
1206         stmg    %r0,%r1,16($sp)
1207         lmg     %r0,%r1,0($key) # copy key, cover 256 bit
1208         stmg    %r0,%r1,32($sp)
1209         lmg     %r0,%r1,16($key)
1210         stmg    %r0,%r1,48($sp)
1211         l       %r0,240($key)   # load kmc code
1212         lghi    $key,15         # res=len%16, len-=res;
1213         ngr     $key,$len
1214         sl${g}r $len,$key
1215         la      %r1,16($sp)     # parameter block - ivec || key
1216         jz      .Lkmc_truncated
1217         .long   0xb92f0042      # kmc %r4,%r2
1218         brc     1,.-4           # pay attention to "partial completion"
1219         ltr     $key,$key
1220         jnz     .Lkmc_truncated
1221 .Lkmc_done:
1222         lmg     %r0,%r1,16($sp) # copy ivec to caller
1223         stg     %r0,0($ivp)
1224         stg     %r1,8($ivp)
1225         br      $ra
1226 .align  16
1227 .Lkmc_truncated:
1228         ahi     $key,-1         # it's the way it's encoded in mvc
1229         tmll    %r0,0x80
1230         jnz     .Lkmc_truncated_dec
1231         lghi    %r1,0
1232         stg     %r1,16*$SIZE_T($sp)
1233         stg     %r1,16*$SIZE_T+8($sp)
1234         bras    %r1,1f
1235         mvc     16*$SIZE_T(1,$sp),0($inp)
1236 1:      ex      $key,0(%r1)
1237         la      %r1,16($sp)     # restore parameter block
1238         la      $inp,16*$SIZE_T($sp)
1239         lghi    $len,16
1240         .long   0xb92f0042      # kmc %r4,%r2
1241         j       .Lkmc_done
1242 .align  16
1243 .Lkmc_truncated_dec:
1244         st${g}  $out,4*$SIZE_T($sp)
1245         la      $out,16*$SIZE_T($sp)
1246         lghi    $len,16
1247         .long   0xb92f0042      # kmc %r4,%r2
1248         l${g}   $out,4*$SIZE_T($sp)
1249         bras    %r1,2f
1250         mvc     0(1,$out),16*$SIZE_T($sp)
1251 2:      ex      $key,0(%r1)
1252         j       .Lkmc_done
1253 .align  16
1254 .Lcbc_software:
1255 ___
1256 $code.=<<___;
1257         stm${g} $key,$ra,5*$SIZE_T($sp)
1258         lhi     %r0,0
1259         cl      %r0,`$stdframe+$SIZE_T-4`($sp)
1260         je      .Lcbc_decrypt
1261
1262         larl    $tbl,AES_Te
1263
1264         llgf    $s0,0($ivp)
1265         llgf    $s1,4($ivp)
1266         llgf    $s2,8($ivp)
1267         llgf    $s3,12($ivp)
1268
1269         lghi    $t0,16
1270         sl${g}r $len,$t0
1271         brc     4,.Lcbc_enc_tail        # if borrow
1272 .Lcbc_enc_loop:
1273         stm${g} $inp,$out,2*$SIZE_T($sp)
1274         x       $s0,0($inp)
1275         x       $s1,4($inp)
1276         x       $s2,8($inp)
1277         x       $s3,12($inp)
1278         lgr     %r4,$key
1279
1280         bras    $ra,_s390x_AES_encrypt
1281
1282         lm${g}  $inp,$key,2*$SIZE_T($sp)
1283         st      $s0,0($out)
1284         st      $s1,4($out)
1285         st      $s2,8($out)
1286         st      $s3,12($out)
1287
1288         la      $inp,16($inp)
1289         la      $out,16($out)
1290         lghi    $t0,16
1291         lt${g}r $len,$len
1292         jz      .Lcbc_enc_done
1293         sl${g}r $len,$t0
1294         brc     4,.Lcbc_enc_tail        # if borrow
1295         j       .Lcbc_enc_loop
1296 .align  16
1297 .Lcbc_enc_done:
1298         l${g}   $ivp,6*$SIZE_T($sp)
1299         st      $s0,0($ivp)
1300         st      $s1,4($ivp)     
1301         st      $s2,8($ivp)
1302         st      $s3,12($ivp)
1303
1304         lm${g}  %r7,$ra,7*$SIZE_T($sp)
1305         br      $ra
1306
1307 .align  16
1308 .Lcbc_enc_tail:
1309         aghi    $len,15
1310         lghi    $t0,0
1311         stg     $t0,16*$SIZE_T($sp)
1312         stg     $t0,16*$SIZE_T+8($sp)
1313         bras    $t1,3f
1314         mvc     16*$SIZE_T(1,$sp),0($inp)
1315 3:      ex      $len,0($t1)
1316         lghi    $len,0
1317         la      $inp,16*$SIZE_T($sp)
1318         j       .Lcbc_enc_loop
1319
1320 .align  16
1321 .Lcbc_decrypt:
1322         larl    $tbl,AES_Td
1323
1324         lg      $t0,0($ivp)
1325         lg      $t1,8($ivp)
1326         stmg    $t0,$t1,16*$SIZE_T($sp)
1327
1328 .Lcbc_dec_loop:
1329         stm${g} $inp,$out,2*$SIZE_T($sp)
1330         llgf    $s0,0($inp)
1331         llgf    $s1,4($inp)
1332         llgf    $s2,8($inp)
1333         llgf    $s3,12($inp)
1334         lgr     %r4,$key
1335
1336         bras    $ra,_s390x_AES_decrypt
1337
1338         lm${g}  $inp,$key,2*$SIZE_T($sp)
1339         sllg    $s0,$s0,32
1340         sllg    $s2,$s2,32
1341         lr      $s0,$s1
1342         lr      $s2,$s3
1343
1344         lg      $t0,0($inp)
1345         lg      $t1,8($inp)
1346         xg      $s0,16*$SIZE_T($sp)
1347         xg      $s2,16*$SIZE_T+8($sp)
1348         lghi    $s1,16
1349         sl${g}r $len,$s1
1350         brc     4,.Lcbc_dec_tail        # if borrow
1351         brc     2,.Lcbc_dec_done        # if zero
1352         stg     $s0,0($out)
1353         stg     $s2,8($out)
1354         stmg    $t0,$t1,16*$SIZE_T($sp)
1355
1356         la      $inp,16($inp)
1357         la      $out,16($out)
1358         j       .Lcbc_dec_loop
1359
1360 .Lcbc_dec_done:
1361         stg     $s0,0($out)
1362         stg     $s2,8($out)
1363 .Lcbc_dec_exit:
1364         lm${g}  %r6,$ra,6*$SIZE_T($sp)
1365         stmg    $t0,$t1,0($ivp)
1366
1367         br      $ra
1368
1369 .align  16
1370 .Lcbc_dec_tail:
1371         aghi    $len,15
1372         stg     $s0,16*$SIZE_T($sp)
1373         stg     $s2,16*$SIZE_T+8($sp)
1374         bras    $s1,4f
1375         mvc     0(1,$out),16*$SIZE_T($sp)
1376 4:      ex      $len,0($s1)
1377         j       .Lcbc_dec_exit
1378 .size   AES_cbc_encrypt,.-AES_cbc_encrypt
1379 ___
1380 }
1381 ########################################################################
1382 # void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
1383 #                     size_t blocks, const AES_KEY *key,
1384 #                     const unsigned char *ivec)
1385 {
1386 my $inp="%r2";
1387 my $out="%r4";  # blocks and out are swapped
1388 my $len="%r3";
1389 my $key="%r5";  my $iv0="%r5";
1390 my $ivp="%r6";
1391 my $fp ="%r7";
1392
1393 $code.=<<___;
1394 .globl  AES_ctr32_encrypt
1395 .type   AES_ctr32_encrypt,\@function
1396 .align  16
1397 AES_ctr32_encrypt:
1398         xgr     %r3,%r4         # flip %r3 and %r4, $out and $len
1399         xgr     %r4,%r3
1400         xgr     %r3,%r4
1401         llgfr   $len,$len       # safe in ctr32 subroutine even in 64-bit case
1402 ___
1403 $code.=<<___ if (!$softonly);
1404         l       %r0,240($key)
1405         lhi     %r1,16
1406         clr     %r0,%r1
1407         jl      .Lctr32_software
1408
1409         stm${g} %r6,$s3,6*$SIZE_T($sp)
1410
1411         slgr    $out,$inp
1412         la      %r1,0($key)     # %r1 is permanent copy of $key
1413         lg      $iv0,0($ivp)    # load ivec
1414         lg      $ivp,8($ivp)
1415
1416         # prepare and allocate stack frame at the top of 4K page
1417         # with 1K reserved for eventual signal handling
1418         lghi    $s0,-1024-256-16# guarantee at least 256-bytes buffer
1419         lghi    $s1,-4096
1420         algr    $s0,$sp
1421         lgr     $fp,$sp
1422         ngr     $s0,$s1         # align at page boundary
1423         slgr    $fp,$s0         # total buffer size
1424         lgr     $s2,$sp
1425         lghi    $s1,1024+16     # sl[g]fi is extended-immediate facility
1426         slgr    $fp,$s1         # deduct reservation to get usable buffer size
1427         # buffer size is at lest 256 and at most 3072+256-16
1428
1429         la      $sp,1024($s0)   # alloca
1430         srlg    $fp,$fp,4       # convert bytes to blocks, minimum 16
1431         st${g}  $s2,0($sp)      # back-chain
1432         st${g}  $fp,$SIZE_T($sp)
1433
1434         slgr    $len,$fp
1435         brc     1,.Lctr32_hw_switch     # not zero, no borrow
1436         algr    $fp,$len        # input is shorter than allocated buffer
1437         lghi    $len,0
1438         st${g}  $fp,$SIZE_T($sp)
1439
1440 .Lctr32_hw_switch:
1441 ___
1442 $code.=<<___ if (0);    ######### kmctr code was measured to be ~12% slower
1443         larl    $s0,OPENSSL_s390xcap_P
1444         lg      $s0,8($s0)
1445         tmhh    $s0,0x0004      # check for message_security-assist-4
1446         jz      .Lctr32_km_loop
1447
1448         llgfr   $s0,%r0
1449         lgr     $s1,%r1
1450         larl    %r1,OPENSSL_s390xcap_P
1451         llihh   %r0,0x8000      # check if kmctr supports the function code
1452         srlg    %r0,%r0,0($s0)
1453         ng      %r0,64(%r1)     # check kmctr capability vector
1454         lgr     %r0,$s0
1455         lgr     %r1,$s1
1456         jz      .Lctr32_km_loop
1457
1458 ####### kmctr code
1459         algr    $out,$inp       # restore $out
1460         lgr     $s1,$len        # $s1 undertakes $len
1461         j       .Lctr32_kmctr_loop
1462 .align  16
1463 .Lctr32_kmctr_loop:
1464         la      $s2,16($sp)
1465         lgr     $s3,$fp
1466 .Lctr32_kmctr_prepare:
1467         stg     $iv0,0($s2)
1468         stg     $ivp,8($s2)
1469         la      $s2,16($s2)
1470         ahi     $ivp,1          # 32-bit increment, preserves upper half
1471         brct    $s3,.Lctr32_kmctr_prepare
1472
1473         #la     $inp,0($inp)    # inp
1474         sllg    $len,$fp,4      # len
1475         #la     $out,0($out)    # out
1476         la      $s2,16($sp)     # iv
1477         .long   0xb92da042      # kmctr $out,$s2,$inp
1478         brc     1,.-4           # pay attention to "partial completion"
1479
1480         slgr    $s1,$fp
1481         brc     1,.Lctr32_kmctr_loop    # not zero, no borrow
1482         algr    $fp,$s1
1483         lghi    $s1,0
1484         brc     4+1,.Lctr32_kmctr_loop  # not zero
1485
1486         l${g}   $sp,0($sp)
1487         lm${g}  %r6,$s3,6*$SIZE_T($sp)
1488         br      $ra
1489 .align  16
1490 ___
1491 $code.=<<___;
1492 .Lctr32_km_loop:
1493         la      $s2,16($sp)
1494         lgr     $s3,$fp
1495 .Lctr32_km_prepare:
1496         stg     $iv0,0($s2)
1497         stg     $ivp,8($s2)
1498         la      $s2,16($s2)
1499         ahi     $ivp,1          # 32-bit increment, preserves upper half
1500         brct    $s3,.Lctr32_km_prepare
1501
1502         la      $s0,16($sp)     # inp
1503         sllg    $s1,$fp,4       # len
1504         la      $s2,16($sp)     # out
1505         .long   0xb92e00a8      # km %r10,%r8
1506         brc     1,.-4           # pay attention to "partial completion"
1507
1508         la      $s2,16($sp)
1509         lgr     $s3,$fp
1510         slgr    $s2,$inp
1511 .Lctr32_km_xor:
1512         lg      $s0,0($inp)
1513         lg      $s1,8($inp)
1514         xg      $s0,0($s2,$inp)
1515         xg      $s1,8($s2,$inp)
1516         stg     $s0,0($out,$inp)
1517         stg     $s1,8($out,$inp)
1518         la      $inp,16($inp)
1519         brct    $s3,.Lctr32_km_xor
1520
1521         slgr    $len,$fp
1522         brc     1,.Lctr32_km_loop       # not zero, no borrow
1523         algr    $fp,$len
1524         lghi    $len,0
1525         brc     4+1,.Lctr32_km_loop     # not zero
1526
1527         l${g}   $s0,0($sp)
1528         l${g}   $s1,$SIZE_T($sp)
1529         la      $s2,16($sp)
1530 .Lctr32_km_zap:
1531         stg     $s0,0($s2)
1532         stg     $s0,8($s2)
1533         la      $s2,16($s2)
1534         brct    $s1,.Lctr32_km_zap
1535
1536         la      $sp,0($s0)
1537         lm${g}  %r6,$s3,6*$SIZE_T($sp)
1538         br      $ra
1539 .align  16
1540 .Lctr32_software:
1541 ___
1542 $code.=<<___;
1543         stm${g} $key,$ra,5*$SIZE_T($sp)
1544         sl${g}r $inp,$out
1545         larl    $tbl,AES_Te
1546         llgf    $t1,12($ivp)
1547
1548 .Lctr32_loop:
1549         stm${g} $inp,$out,2*$SIZE_T($sp)
1550         llgf    $s0,0($ivp)
1551         llgf    $s1,4($ivp)
1552         llgf    $s2,8($ivp)
1553         lgr     $s3,$t1
1554         st      $t1,16*$SIZE_T($sp)
1555         lgr     %r4,$key
1556
1557         bras    $ra,_s390x_AES_encrypt
1558
1559         lm${g}  $inp,$ivp,2*$SIZE_T($sp)
1560         llgf    $t1,16*$SIZE_T($sp)
1561         x       $s0,0($inp,$out)
1562         x       $s1,4($inp,$out)
1563         x       $s2,8($inp,$out)
1564         x       $s3,12($inp,$out)
1565         stm     $s0,$s3,0($out)
1566
1567         la      $out,16($out)
1568         ahi     $t1,1           # 32-bit increment
1569         brct    $len,.Lctr32_loop
1570
1571         lm${g}  %r6,$ra,6*$SIZE_T($sp)
1572         br      $ra
1573 .size   AES_ctr32_encrypt,.-AES_ctr32_encrypt
1574 ___
1575 }
1576
1577 ########################################################################
1578 # void AES_xts_encrypt(const char *inp,char *out,size_t len,
1579 #       const AES_KEY *key1, const AES_KEY *key2,
1580 #       const unsigned char iv[16]);
1581 #
1582 {
1583 my $inp="%r2";
1584 my $out="%r4";  # len and out are swapped
1585 my $len="%r3";
1586 my $key1="%r5"; # $i1
1587 my $key2="%r6"; # $i2
1588 my $fp="%r7";   # $i3
1589 my $tweak=16*$SIZE_T+16;        # or $stdframe-16, bottom of the frame...
1590
1591 $code.=<<___;
1592 .type   _s390x_xts_km,\@function
1593 .align  16
1594 _s390x_xts_km:
1595 ___
1596 $code.=<<___ if(1);
1597         llgfr   $s0,%r0                 # put aside the function code
1598         lghi    $s1,0x7f
1599         nr      $s1,%r0
1600         larl    %r1,OPENSSL_s390xcap_P
1601         llihh   %r0,0x8000
1602         srlg    %r0,%r0,32($s1)         # check for 32+function code
1603         ng      %r0,32(%r1)             # check km capability vector
1604         lgr     %r0,$s0                 # restore the function code
1605         la      %r1,0($key1)            # restore $key1
1606         jz      .Lxts_km_vanilla
1607
1608         lmg     $i2,$i3,$tweak($sp)     # put aside the tweak value
1609         algr    $out,$inp
1610
1611         oill    %r0,32                  # switch to xts function code
1612         aghi    $s1,-18                 #
1613         sllg    $s1,$s1,3               # (function code - 18)*8, 0 or 16
1614         la      %r1,$tweak-16($sp)
1615         slgr    %r1,$s1                 # parameter block position
1616         lmg     $s0,$s3,0($key1)        # load 256 bits of key material,
1617         stmg    $s0,$s3,0(%r1)          # and copy it to parameter block.
1618                                         # yes, it contains junk and overlaps
1619                                         # with the tweak in 128-bit case.
1620                                         # it's done to avoid conditional
1621                                         # branch.
1622         stmg    $i2,$i3,$tweak($sp)     # "re-seat" the tweak value
1623
1624         .long   0xb92e0042              # km %r4,%r2
1625         brc     1,.-4                   # pay attention to "partial completion"
1626
1627         lrvg    $s0,$tweak+0($sp)       # load the last tweak
1628         lrvg    $s1,$tweak+8($sp)
1629         stmg    %r0,%r3,$tweak-32($sp)  # wipe copy of the key
1630
1631         nill    %r0,0xffdf              # switch back to original function code
1632         la      %r1,0($key1)            # restore pointer to $key1
1633         slgr    $out,$inp
1634
1635         llgc    $len,2*$SIZE_T-1($sp)
1636         nill    $len,0x0f               # $len%=16
1637         br      $ra
1638         
1639 .align  16
1640 .Lxts_km_vanilla:
1641 ___
1642 $code.=<<___;
1643         # prepare and allocate stack frame at the top of 4K page
1644         # with 1K reserved for eventual signal handling
1645         lghi    $s0,-1024-256-16# guarantee at least 256-bytes buffer
1646         lghi    $s1,-4096
1647         algr    $s0,$sp
1648         lgr     $fp,$sp
1649         ngr     $s0,$s1         # align at page boundary
1650         slgr    $fp,$s0         # total buffer size
1651         lgr     $s2,$sp
1652         lghi    $s1,1024+16     # sl[g]fi is extended-immediate facility
1653         slgr    $fp,$s1         # deduct reservation to get usable buffer size
1654         # buffer size is at lest 256 and at most 3072+256-16
1655
1656         la      $sp,1024($s0)   # alloca
1657         nill    $fp,0xfff0      # round to 16*n
1658         st${g}  $s2,0($sp)      # back-chain
1659         nill    $len,0xfff0     # redundant
1660         st${g}  $fp,$SIZE_T($sp)
1661
1662         slgr    $len,$fp
1663         brc     1,.Lxts_km_go   # not zero, no borrow
1664         algr    $fp,$len        # input is shorter than allocated buffer
1665         lghi    $len,0
1666         st${g}  $fp,$SIZE_T($sp)
1667
1668 .Lxts_km_go:
1669         lrvg    $s0,$tweak+0($s2)       # load the tweak value in little-endian
1670         lrvg    $s1,$tweak+8($s2)
1671
1672         la      $s2,16($sp)             # vector of ascending tweak values
1673         slgr    $s2,$inp
1674         srlg    $s3,$fp,4
1675         j       .Lxts_km_start
1676
1677 .Lxts_km_loop:
1678         la      $s2,16($sp)
1679         slgr    $s2,$inp
1680         srlg    $s3,$fp,4
1681 .Lxts_km_prepare:
1682         lghi    $i1,0x87
1683         srag    $i2,$s1,63              # broadcast upper bit
1684         ngr     $i1,$i2                 # rem
1685         algr    $s0,$s0
1686         alcgr   $s1,$s1
1687         xgr     $s0,$i1
1688 .Lxts_km_start:
1689         lrvgr   $i1,$s0                 # flip byte order
1690         lrvgr   $i2,$s1
1691         stg     $i1,0($s2,$inp)
1692         stg     $i2,8($s2,$inp)
1693         xg      $i1,0($inp)
1694         xg      $i2,8($inp)
1695         stg     $i1,0($out,$inp)
1696         stg     $i2,8($out,$inp)
1697         la      $inp,16($inp)
1698         brct    $s3,.Lxts_km_prepare
1699
1700         slgr    $inp,$fp                # rewind $inp
1701         la      $s2,0($out,$inp)
1702         lgr     $s3,$fp
1703         .long   0xb92e00aa              # km $s2,$s2
1704         brc     1,.-4                   # pay attention to "partial completion"
1705
1706         la      $s2,16($sp)
1707         slgr    $s2,$inp
1708         srlg    $s3,$fp,4
1709 .Lxts_km_xor:
1710         lg      $i1,0($out,$inp)
1711         lg      $i2,8($out,$inp)
1712         xg      $i1,0($s2,$inp)
1713         xg      $i2,8($s2,$inp)
1714         stg     $i1,0($out,$inp)
1715         stg     $i2,8($out,$inp)
1716         la      $inp,16($inp)
1717         brct    $s3,.Lxts_km_xor
1718
1719         slgr    $len,$fp
1720         brc     1,.Lxts_km_loop         # not zero, no borrow
1721         algr    $fp,$len
1722         lghi    $len,0
1723         brc     4+1,.Lxts_km_loop       # not zero
1724
1725         l${g}   $i1,0($sp)              # back-chain
1726         llgf    $fp,`2*$SIZE_T-4`($sp)  # bytes used
1727         la      $i2,16($sp)
1728         srlg    $fp,$fp,4
1729 .Lxts_km_zap:
1730         stg     $i1,0($i2)
1731         stg     $i1,8($i2)
1732         la      $i2,16($i2)
1733         brct    $fp,.Lxts_km_zap
1734
1735         la      $sp,0($i1)
1736         llgc    $len,2*$SIZE_T-1($i1)
1737         nill    $len,0x0f               # $len%=16
1738         bzr     $ra
1739
1740         # generate one more tweak...
1741         lghi    $i1,0x87
1742         srag    $i2,$s1,63              # broadcast upper bit
1743         ngr     $i1,$i2                 # rem
1744         algr    $s0,$s0
1745         alcgr   $s1,$s1
1746         xgr     $s0,$i1
1747
1748         ltr     $len,$len               # clear zero flag
1749         br      $ra
1750 .size   _s390x_xts_km,.-_s390x_xts_km
1751
1752 .globl  AES_xts_encrypt
1753 .type   AES_xts_encrypt,\@function
1754 .align  16
1755 AES_xts_encrypt:
1756         xgr     %r3,%r4                 # flip %r3 and %r4, $out and $len
1757         xgr     %r4,%r3
1758         xgr     %r3,%r4
1759 ___
1760 $code.=<<___ if ($SIZE_T==4);
1761         llgfr   $len,$len
1762 ___
1763 $code.=<<___;
1764         st${g}  $len,1*$SIZE_T($sp)     # save copy of $len
1765         srag    $len,$len,4             # formally wrong, because it expands
1766                                         # sign byte, but who can afford asking
1767                                         # to process more than 2^63-1 bytes?
1768                                         # I use it, because it sets condition
1769                                         # code...
1770         bcr     8,$ra                   # abort if zero (i.e. less than 16)
1771 ___
1772 $code.=<<___ if (!$softonly);
1773         llgf    %r0,240($key2)
1774         lhi     %r1,16
1775         clr     %r0,%r1
1776         jl      .Lxts_enc_software
1777
1778         st${g}  $ra,5*$SIZE_T($sp)
1779         stm${g} %r6,$s3,6*$SIZE_T($sp)
1780
1781         sllg    $len,$len,4             # $len&=~15
1782         slgr    $out,$inp
1783
1784         # generate the tweak value
1785         l${g}   $s3,$stdframe($sp)      # pointer to iv
1786         la      $s2,$tweak($sp)
1787         lmg     $s0,$s1,0($s3)
1788         lghi    $s3,16
1789         stmg    $s0,$s1,0($s2)
1790         la      %r1,0($key2)            # $key2 is not needed anymore
1791         .long   0xb92e00aa              # km $s2,$s2, generate the tweak
1792         brc     1,.-4                   # can this happen?
1793
1794         l       %r0,240($key1)
1795         la      %r1,0($key1)            # $key1 is not needed anymore
1796         bras    $ra,_s390x_xts_km
1797         jz      .Lxts_enc_km_done
1798
1799         aghi    $inp,-16                # take one step back
1800         la      $i3,0($out,$inp)        # put aside real $out
1801 .Lxts_enc_km_steal:
1802         llgc    $i1,16($inp)
1803         llgc    $i2,0($out,$inp)
1804         stc     $i1,0($out,$inp)
1805         stc     $i2,16($out,$inp)
1806         la      $inp,1($inp)
1807         brct    $len,.Lxts_enc_km_steal
1808
1809         la      $s2,0($i3)
1810         lghi    $s3,16
1811         lrvgr   $i1,$s0                 # flip byte order
1812         lrvgr   $i2,$s1
1813         xg      $i1,0($s2)
1814         xg      $i2,8($s2)
1815         stg     $i1,0($s2)
1816         stg     $i2,8($s2)
1817         .long   0xb92e00aa              # km $s2,$s2
1818         brc     1,.-4                   # can this happen?
1819         lrvgr   $i1,$s0                 # flip byte order
1820         lrvgr   $i2,$s1
1821         xg      $i1,0($i3)
1822         xg      $i2,8($i3)
1823         stg     $i1,0($i3)
1824         stg     $i2,8($i3)
1825
1826 .Lxts_enc_km_done:
1827         stg     $sp,$tweak+0($sp)       # wipe tweak
1828         stg     $sp,$tweak+8($sp)
1829         l${g}   $ra,5*$SIZE_T($sp)
1830         lm${g}  %r6,$s3,6*$SIZE_T($sp)
1831         br      $ra
1832 .align  16
1833 .Lxts_enc_software:
1834 ___
1835 $code.=<<___;
1836         stm${g} %r6,$ra,6*$SIZE_T($sp)
1837
1838         slgr    $out,$inp
1839
1840         l${g}   $s3,$stdframe($sp)      # ivp
1841         llgf    $s0,0($s3)              # load iv
1842         llgf    $s1,4($s3)
1843         llgf    $s2,8($s3)
1844         llgf    $s3,12($s3)
1845         stm${g} %r2,%r5,2*$SIZE_T($sp)
1846         la      $key,0($key2)
1847         larl    $tbl,AES_Te
1848         bras    $ra,_s390x_AES_encrypt  # generate the tweak
1849         lm${g}  %r2,%r5,2*$SIZE_T($sp)
1850         stm     $s0,$s3,$tweak($sp)     # save the tweak
1851         j       .Lxts_enc_enter
1852
1853 .align  16
1854 .Lxts_enc_loop:
1855         lrvg    $s1,$tweak+0($sp)       # load the tweak in little-endian
1856         lrvg    $s3,$tweak+8($sp)
1857         lghi    %r1,0x87
1858         srag    %r0,$s3,63              # broadcast upper bit
1859         ngr     %r1,%r0                 # rem
1860         algr    $s1,$s1
1861         alcgr   $s3,$s3
1862         xgr     $s1,%r1
1863         lrvgr   $s1,$s1                 # flip byte order
1864         lrvgr   $s3,$s3
1865         srlg    $s0,$s1,32              # smash the tweak to 4x32-bits 
1866         stg     $s1,$tweak+0($sp)       # save the tweak
1867         llgfr   $s1,$s1
1868         srlg    $s2,$s3,32
1869         stg     $s3,$tweak+8($sp)
1870         llgfr   $s3,$s3
1871         la      $inp,16($inp)           # $inp+=16
1872 .Lxts_enc_enter:
1873         x       $s0,0($inp)             # ^=*($inp)
1874         x       $s1,4($inp)
1875         x       $s2,8($inp)
1876         x       $s3,12($inp)
1877         stm${g} %r2,%r3,2*$SIZE_T($sp)  # only two registers are changing
1878         la      $key,0($key1)
1879         bras    $ra,_s390x_AES_encrypt
1880         lm${g}  %r2,%r5,2*$SIZE_T($sp)
1881         x       $s0,$tweak+0($sp)       # ^=tweak
1882         x       $s1,$tweak+4($sp)
1883         x       $s2,$tweak+8($sp)
1884         x       $s3,$tweak+12($sp)
1885         st      $s0,0($out,$inp)
1886         st      $s1,4($out,$inp)
1887         st      $s2,8($out,$inp)
1888         st      $s3,12($out,$inp)
1889         brct${g}        $len,.Lxts_enc_loop
1890
1891         llgc    $len,`2*$SIZE_T-1`($sp)
1892         nill    $len,0x0f               # $len%16
1893         jz      .Lxts_enc_done
1894
1895         la      $i3,0($inp,$out)        # put aside real $out
1896 .Lxts_enc_steal:
1897         llgc    %r0,16($inp)
1898         llgc    %r1,0($out,$inp)
1899         stc     %r0,0($out,$inp)
1900         stc     %r1,16($out,$inp)
1901         la      $inp,1($inp)
1902         brct    $len,.Lxts_enc_steal
1903         la      $out,0($i3)             # restore real $out
1904
1905         # generate last tweak...
1906         lrvg    $s1,$tweak+0($sp)       # load the tweak in little-endian
1907         lrvg    $s3,$tweak+8($sp)
1908         lghi    %r1,0x87
1909         srag    %r0,$s3,63              # broadcast upper bit
1910         ngr     %r1,%r0                 # rem
1911         algr    $s1,$s1
1912         alcgr   $s3,$s3
1913         xgr     $s1,%r1
1914         lrvgr   $s1,$s1                 # flip byte order
1915         lrvgr   $s3,$s3
1916         srlg    $s0,$s1,32              # smash the tweak to 4x32-bits 
1917         stg     $s1,$tweak+0($sp)       # save the tweak
1918         llgfr   $s1,$s1
1919         srlg    $s2,$s3,32
1920         stg     $s3,$tweak+8($sp)
1921         llgfr   $s3,$s3
1922
1923         x       $s0,0($out)             # ^=*(inp)|stolen cipther-text
1924         x       $s1,4($out)
1925         x       $s2,8($out)
1926         x       $s3,12($out)
1927         st${g}  $out,4*$SIZE_T($sp)
1928         la      $key,0($key1)
1929         bras    $ra,_s390x_AES_encrypt
1930         l${g}   $out,4*$SIZE_T($sp)
1931         x       $s0,`$tweak+0`($sp)     # ^=tweak
1932         x       $s1,`$tweak+4`($sp)
1933         x       $s2,`$tweak+8`($sp)
1934         x       $s3,`$tweak+12`($sp)
1935         st      $s0,0($out)
1936         st      $s1,4($out)
1937         st      $s2,8($out)
1938         st      $s3,12($out)
1939
1940 .Lxts_enc_done:
1941         stg     $sp,$tweak+0($sp)       # wipe tweak
1942         stg     $sp,$twesk+8($sp)
1943         lm${g}  %r6,$ra,6*$SIZE_T($sp)
1944         br      $ra
1945 .size   AES_xts_encrypt,.-AES_xts_encrypt
1946 ___
1947 # void AES_xts_decrypt(const char *inp,char *out,size_t len,
1948 #       const AES_KEY *key1, const AES_KEY *key2,
1949 #       const unsigned char iv[16]);
1950 #
1951 $code.=<<___;
1952 .globl  AES_xts_decrypt
1953 .type   AES_xts_decrypt,\@function
1954 .align  16
1955 AES_xts_decrypt:
1956         xgr     %r3,%r4                 # flip %r3 and %r4, $out and $len
1957         xgr     %r4,%r3
1958         xgr     %r3,%r4
1959 ___
1960 $code.=<<___ if ($SIZE_T==4);
1961         llgfr   $len,$len
1962 ___
1963 $code.=<<___;
1964         st${g}  $len,1*$SIZE_T($sp)     # save copy of $len
1965         aghi    $len,-16
1966         bcr     4,$ra                   # abort if less than zero. formally
1967                                         # wrong, because $len is unsigned,
1968                                         # but who can afford asking to
1969                                         # process more than 2^63-1 bytes?
1970         tmll    $len,0x0f
1971         jnz     .Lxts_dec_proceed
1972         aghi    $len,16
1973 .Lxts_dec_proceed:
1974 ___
1975 $code.=<<___ if (!$softonly);
1976         llgf    %r0,240($key2)
1977         lhi     %r1,16
1978         clr     %r0,%r1
1979         jl      .Lxts_dec_software
1980
1981         st${g}  $ra,5*$SIZE_T($sp)
1982         stm${g} %r6,$s3,6*$SIZE_T($sp)
1983
1984         nill    $len,0xfff0             # $len&=~15
1985         slgr    $out,$inp
1986
1987         # generate the tweak value
1988         l${g}   $s3,$stdframe($sp)      # pointer to iv
1989         la      $s2,$tweak($sp)
1990         lmg     $s0,$s1,0($s3)
1991         lghi    $s3,16
1992         stmg    $s0,$s1,0($s2)
1993         la      %r1,0($key2)            # $key2 is not needed past this point
1994         .long   0xb92e00aa              # km $s2,$s2, generate the tweak
1995         brc     1,.-4                   # can this happen?
1996
1997         l       %r0,240($key1)
1998         la      %r1,0($key1)            # $key1 is not needed anymore
1999
2000         ltgr    $len,$len
2001         jz      .Lxts_dec_km_short
2002         bras    $ra,_s390x_xts_km
2003         jz      .Lxts_dec_km_done
2004
2005         lrvgr   $s2,$s0                 # make copy in reverse byte order
2006         lrvgr   $s3,$s1
2007         j       .Lxts_dec_km_2ndtweak
2008
2009 .Lxts_dec_km_short:
2010         llgc    $len,`2*$SIZE_T-1`($sp)
2011         nill    $len,0x0f               # $len%=16
2012         lrvg    $s0,$tweak+0($sp)       # load the tweak
2013         lrvg    $s1,$tweak+8($sp)
2014         lrvgr   $s2,$s0                 # make copy in reverse byte order
2015         lrvgr   $s3,$s1
2016
2017 .Lxts_dec_km_2ndtweak:
2018         lghi    $i1,0x87
2019         srag    $i2,$s1,63              # broadcast upper bit
2020         ngr     $i1,$i2                 # rem
2021         algr    $s0,$s0
2022         alcgr   $s1,$s1
2023         xgr     $s0,$i1
2024         lrvgr   $i1,$s0                 # flip byte order
2025         lrvgr   $i2,$s1
2026
2027         xg      $i1,0($inp)
2028         xg      $i2,8($inp)
2029         stg     $i1,0($out,$inp)
2030         stg     $i2,8($out,$inp)
2031         la      $i2,0($out,$inp)
2032         lghi    $i3,16
2033         .long   0xb92e0066              # km $i2,$i2
2034         brc     1,.-4                   # can this happen?
2035         lrvgr   $i1,$s0
2036         lrvgr   $i2,$s1
2037         xg      $i1,0($out,$inp)
2038         xg      $i2,8($out,$inp)
2039         stg     $i1,0($out,$inp)
2040         stg     $i2,8($out,$inp)
2041
2042         la      $i3,0($out,$inp)        # put aside real $out
2043 .Lxts_dec_km_steal:
2044         llgc    $i1,16($inp)
2045         llgc    $i2,0($out,$inp)
2046         stc     $i1,0($out,$inp)
2047         stc     $i2,16($out,$inp)
2048         la      $inp,1($inp)
2049         brct    $len,.Lxts_dec_km_steal
2050
2051         lgr     $s0,$s2
2052         lgr     $s1,$s3
2053         xg      $s0,0($i3)
2054         xg      $s1,8($i3)
2055         stg     $s0,0($i3)
2056         stg     $s1,8($i3)
2057         la      $s0,0($i3)
2058         lghi    $s1,16
2059         .long   0xb92e0088              # km $s0,$s0
2060         brc     1,.-4                   # can this happen?
2061         xg      $s2,0($i3)
2062         xg      $s3,8($i3)
2063         stg     $s2,0($i3)
2064         stg     $s3,8($i3)
2065 .Lxts_dec_km_done:
2066         stg     $sp,$tweak+0($sp)       # wipe tweak
2067         stg     $sp,$tweak+8($sp)
2068         l${g}   $ra,5*$SIZE_T($sp)
2069         lm${g}  %r6,$s3,6*$SIZE_T($sp)
2070         br      $ra
2071 .align  16
2072 .Lxts_dec_software:
2073 ___
2074 $code.=<<___;
2075         stm${g} %r6,$ra,6*$SIZE_T($sp)
2076
2077         srlg    $len,$len,4
2078         slgr    $out,$inp
2079
2080         l${g}   $s3,$stdframe($sp)      # ivp
2081         llgf    $s0,0($s3)              # load iv
2082         llgf    $s1,4($s3)
2083         llgf    $s2,8($s3)
2084         llgf    $s3,12($s3)
2085         stm${g} %r2,%r5,2*$SIZE_T($sp)
2086         la      $key,0($key2)
2087         larl    $tbl,AES_Te
2088         bras    $ra,_s390x_AES_encrypt  # generate the tweak
2089         lm${g}  %r2,%r5,2*$SIZE_T($sp)
2090         larl    $tbl,AES_Td
2091         lt${g}r $len,$len
2092         stm     $s0,$s3,$tweak($sp)     # save the tweak
2093         jz      .Lxts_dec_short
2094         j       .Lxts_dec_enter
2095
2096 .align  16
2097 .Lxts_dec_loop:
2098         lrvg    $s1,$tweak+0($sp)       # load the tweak in little-endian
2099         lrvg    $s3,$tweak+8($sp)
2100         lghi    %r1,0x87
2101         srag    %r0,$s3,63              # broadcast upper bit
2102         ngr     %r1,%r0                 # rem
2103         algr    $s1,$s1
2104         alcgr   $s3,$s3
2105         xgr     $s1,%r1
2106         lrvgr   $s1,$s1                 # flip byte order
2107         lrvgr   $s3,$s3
2108         srlg    $s0,$s1,32              # smash the tweak to 4x32-bits 
2109         stg     $s1,$tweak+0($sp)       # save the tweak
2110         llgfr   $s1,$s1
2111         srlg    $s2,$s3,32
2112         stg     $s3,$tweak+8($sp)
2113         llgfr   $s3,$s3
2114 .Lxts_dec_enter:
2115         x       $s0,0($inp)             # tweak^=*(inp)
2116         x       $s1,4($inp)
2117         x       $s2,8($inp)
2118         x       $s3,12($inp)
2119         stm${g} %r2,%r3,2*$SIZE_T($sp)  # only two registers are changing
2120         la      $key,0($key1)
2121         bras    $ra,_s390x_AES_decrypt
2122         lm${g}  %r2,%r5,2*$SIZE_T($sp)
2123         x       $s0,$tweak+0($sp)       # ^=tweak
2124         x       $s1,$tweak+4($sp)
2125         x       $s2,$tweak+8($sp)
2126         x       $s3,$tweak+12($sp)
2127         st      $s0,0($out,$inp)
2128         st      $s1,4($out,$inp)
2129         st      $s2,8($out,$inp)
2130         st      $s3,12($out,$inp)
2131         la      $inp,16($inp)
2132         brct${g}        $len,.Lxts_dec_loop
2133
2134         llgc    $len,`2*$SIZE_T-1`($sp)
2135         nill    $len,0x0f               # $len%16
2136         jz      .Lxts_dec_done
2137
2138         # generate pair of tweaks...
2139         lrvg    $s1,$tweak+0($sp)       # load the tweak in little-endian
2140         lrvg    $s3,$tweak+8($sp)
2141         lghi    %r1,0x87
2142         srag    %r0,$s3,63              # broadcast upper bit
2143         ngr     %r1,%r0                 # rem
2144         algr    $s1,$s1
2145         alcgr   $s3,$s3
2146         xgr     $s1,%r1
2147         lrvgr   $i2,$s1                 # flip byte order
2148         lrvgr   $i3,$s3
2149         stmg    $i2,$i3,$tweak($sp)     # save the 1st tweak
2150         j       .Lxts_dec_2ndtweak
2151
2152 .align  16
2153 .Lxts_dec_short:
2154         llgc    $len,`2*$SIZE_T-1`($sp)
2155         nill    $len,0x0f               # $len%16
2156         lrvg    $s1,$tweak+0($sp)       # load the tweak in little-endian
2157         lrvg    $s3,$tweak+8($sp)
2158 .Lxts_dec_2ndtweak:
2159         lghi    %r1,0x87
2160         srag    %r0,$s3,63              # broadcast upper bit
2161         ngr     %r1,%r0                 # rem
2162         algr    $s1,$s1
2163         alcgr   $s3,$s3
2164         xgr     $s1,%r1
2165         lrvgr   $s1,$s1                 # flip byte order
2166         lrvgr   $s3,$s3
2167         srlg    $s0,$s1,32              # smash the tweak to 4x32-bits
2168         stg     $s1,$tweak-16+0($sp)    # save the 2nd tweak
2169         llgfr   $s1,$s1
2170         srlg    $s2,$s3,32
2171         stg     $s3,$tweak-16+8($sp)
2172         llgfr   $s3,$s3
2173
2174         x       $s0,0($inp)             # tweak_the_2nd^=*(inp)
2175         x       $s1,4($inp)
2176         x       $s2,8($inp)
2177         x       $s3,12($inp)
2178         stm${g} %r2,%r3,2*$SIZE_T($sp)
2179         la      $key,0($key1)
2180         bras    $ra,_s390x_AES_decrypt
2181         lm${g}  %r2,%r5,2*$SIZE_T($sp)
2182         x       $s0,$tweak-16+0($sp)    # ^=tweak_the_2nd
2183         x       $s1,$tweak-16+4($sp)
2184         x       $s2,$tweak-16+8($sp)
2185         x       $s3,$tweak-16+12($sp)
2186         st      $s0,0($out,$inp)
2187         st      $s1,4($out,$inp)
2188         st      $s2,8($out,$inp)
2189         st      $s3,12($out,$inp)
2190
2191         la      $i3,0($out,$inp)        # put aside real $out
2192 .Lxts_dec_steal:
2193         llgc    %r0,16($inp)
2194         llgc    %r1,0($out,$inp)
2195         stc     %r0,0($out,$inp)
2196         stc     %r1,16($out,$inp)
2197         la      $inp,1($inp)
2198         brct    $len,.Lxts_dec_steal
2199         la      $out,0($i3)             # restore real $out
2200
2201         lm      $s0,$s3,$tweak($sp)     # load the 1st tweak
2202         x       $s0,0($out)             # tweak^=*(inp)|stolen cipher-text
2203         x       $s1,4($out)
2204         x       $s2,8($out)
2205         x       $s3,12($out)
2206         st${g}  $out,4*$SIZE_T($sp)
2207         la      $key,0($key1)
2208         bras    $ra,_s390x_AES_decrypt
2209         l${g}   $out,4*$SIZE_T($sp)
2210         x       $s0,$tweak+0($sp)       # ^=tweak
2211         x       $s1,$tweak+4($sp)
2212         x       $s2,$tweak+8($sp)
2213         x       $s3,$tweak+12($sp)
2214         st      $s0,0($out)
2215         st      $s1,4($out)
2216         st      $s2,8($out)
2217         st      $s3,12($out)
2218         stg     $sp,$tweak-16+0($sp)    # wipe 2nd tweak
2219         stg     $sp,$tweak-16+8($sp)
2220 .Lxts_dec_done:
2221         stg     $sp,$tweak+0($sp)       # wipe tweak
2222         stg     $sp,$twesk+8($sp)
2223         lm${g}  %r6,$ra,6*$SIZE_T($sp)
2224         br      $ra
2225 .size   AES_xts_decrypt,.-AES_xts_decrypt
2226 ___
2227 }
2228 $code.=<<___;
2229 .string "AES for s390x, CRYPTOGAMS by <appro\@openssl.org>"
2230 .comm   OPENSSL_s390xcap_P,80,8
2231 ___
2232
2233 $code =~ s/\`([^\`]*)\`/eval $1/gem;
2234 print $code;
2235 close STDOUT;   # force flush