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