77b4640bd6d9aebc70dbc1a4e196e3c2b76fa612
[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@openssl.org> 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(c) 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         llihh   %r0,0x8000
825         srlg    %r0,%r0,0(%r5)
826         ng      %r0,32(%r1)     # check availability of both km...
827         ng      %r0,48(%r1)     # ...and kmc support for given key length
828         jz      .Lekey_internal
829
830         lmg     %r0,%r1,0($inp) # just copy 128 bits...
831         stmg    %r0,%r1,0($key)
832         lhi     %r0,192
833         cr      $bits,%r0
834         jl      1f
835         lg      %r1,16($inp)
836         stg     %r1,16($key)
837         je      1f
838         lg      %r1,24($inp)
839         stg     %r1,24($key)
840 1:      st      $bits,236($key) # save bits [for debugging purposes]
841         lgr     $t0,%r5
842         st      %r5,240($key)   # save km(c) code
843         lghi    %r2,0
844         br      %r14
845 ___
846 $code.=<<___;
847 .align  16
848 .Lekey_internal:
849         stm${g} %r4,%r13,4*$SIZE_T($sp) # all non-volatile regs and $key
850
851         larl    $tbl,AES_Te+2048
852
853         llgf    $s0,0($inp)
854         llgf    $s1,4($inp)
855         llgf    $s2,8($inp)
856         llgf    $s3,12($inp)
857         st      $s0,0($key)
858         st      $s1,4($key)
859         st      $s2,8($key)
860         st      $s3,12($key)
861         lghi    $t0,128
862         cr      $bits,$t0
863         jne     .Lnot128
864
865         llill   $mask,0xff
866         lghi    $t3,0                   # i=0
867         lghi    $rounds,10
868         st      $rounds,240($key)
869
870         llgfr   $t2,$s3                 # temp=rk[3]
871         srlg    $i1,$s3,8
872         srlg    $i2,$s3,16
873         srlg    $i3,$s3,24
874         nr      $t2,$mask
875         nr      $i1,$mask
876         nr      $i2,$mask
877
878 .align  16
879 .L128_loop:
880         la      $t2,0($t2,$tbl)
881         la      $i1,0($i1,$tbl)
882         la      $i2,0($i2,$tbl)
883         la      $i3,0($i3,$tbl)
884         icm     $t2,2,0($t2)            # Te4[rk[3]>>0]<<8
885         icm     $t2,4,0($i1)            # Te4[rk[3]>>8]<<16
886         icm     $t2,8,0($i2)            # Te4[rk[3]>>16]<<24
887         icm     $t2,1,0($i3)            # Te4[rk[3]>>24]
888         x       $t2,256($t3,$tbl)       # rcon[i]
889         xr      $s0,$t2                 # rk[4]=rk[0]^...
890         xr      $s1,$s0                 # rk[5]=rk[1]^rk[4]
891         xr      $s2,$s1                 # rk[6]=rk[2]^rk[5]
892         xr      $s3,$s2                 # rk[7]=rk[3]^rk[6]
893
894         llgfr   $t2,$s3                 # temp=rk[3]
895         srlg    $i1,$s3,8
896         srlg    $i2,$s3,16
897         nr      $t2,$mask
898         nr      $i1,$mask
899         srlg    $i3,$s3,24
900         nr      $i2,$mask
901
902         st      $s0,16($key)
903         st      $s1,20($key)
904         st      $s2,24($key)
905         st      $s3,28($key)
906         la      $key,16($key)           # key+=4
907         la      $t3,4($t3)              # i++
908         brct    $rounds,.L128_loop
909         lghi    $t0,10
910         lghi    %r2,0
911         lm${g}  %r4,%r13,4*$SIZE_T($sp)
912         br      $ra
913
914 .align  16
915 .Lnot128:
916         llgf    $t0,16($inp)
917         llgf    $t1,20($inp)
918         st      $t0,16($key)
919         st      $t1,20($key)
920         lghi    $t0,192
921         cr      $bits,$t0
922         jne     .Lnot192
923
924         llill   $mask,0xff
925         lghi    $t3,0                   # i=0
926         lghi    $rounds,12
927         st      $rounds,240($key)
928         lghi    $rounds,8
929
930         srlg    $i1,$t1,8
931         srlg    $i2,$t1,16
932         srlg    $i3,$t1,24
933         nr      $t1,$mask
934         nr      $i1,$mask
935         nr      $i2,$mask
936
937 .align  16
938 .L192_loop:
939         la      $t1,0($t1,$tbl)
940         la      $i1,0($i1,$tbl)
941         la      $i2,0($i2,$tbl)
942         la      $i3,0($i3,$tbl)
943         icm     $t1,2,0($t1)            # Te4[rk[5]>>0]<<8
944         icm     $t1,4,0($i1)            # Te4[rk[5]>>8]<<16
945         icm     $t1,8,0($i2)            # Te4[rk[5]>>16]<<24
946         icm     $t1,1,0($i3)            # Te4[rk[5]>>24]
947         x       $t1,256($t3,$tbl)       # rcon[i]
948         xr      $s0,$t1                 # rk[6]=rk[0]^...
949         xr      $s1,$s0                 # rk[7]=rk[1]^rk[6]
950         xr      $s2,$s1                 # rk[8]=rk[2]^rk[7]
951         xr      $s3,$s2                 # rk[9]=rk[3]^rk[8]
952
953         st      $s0,24($key)
954         st      $s1,28($key)
955         st      $s2,32($key)
956         st      $s3,36($key)
957         brct    $rounds,.L192_continue
958         lghi    $t0,12
959         lghi    %r2,0
960         lm${g}  %r4,%r13,4*$SIZE_T($sp)
961         br      $ra
962
963 .align  16
964 .L192_continue:
965         lgr     $t1,$s3
966         x       $t1,16($key)            # rk[10]=rk[4]^rk[9]
967         st      $t1,40($key)
968         x       $t1,20($key)            # rk[11]=rk[5]^rk[10]
969         st      $t1,44($key)
970
971         srlg    $i1,$t1,8
972         srlg    $i2,$t1,16
973         srlg    $i3,$t1,24
974         nr      $t1,$mask
975         nr      $i1,$mask
976         nr      $i2,$mask
977
978         la      $key,24($key)           # key+=6
979         la      $t3,4($t3)              # i++
980         j       .L192_loop
981
982 .align  16
983 .Lnot192:
984         llgf    $t0,24($inp)
985         llgf    $t1,28($inp)
986         st      $t0,24($key)
987         st      $t1,28($key)
988         llill   $mask,0xff
989         lghi    $t3,0                   # i=0
990         lghi    $rounds,14
991         st      $rounds,240($key)
992         lghi    $rounds,7
993
994         srlg    $i1,$t1,8
995         srlg    $i2,$t1,16
996         srlg    $i3,$t1,24
997         nr      $t1,$mask
998         nr      $i1,$mask
999         nr      $i2,$mask
1000
1001 .align  16
1002 .L256_loop:
1003         la      $t1,0($t1,$tbl)
1004         la      $i1,0($i1,$tbl)
1005         la      $i2,0($i2,$tbl)
1006         la      $i3,0($i3,$tbl)
1007         icm     $t1,2,0($t1)            # Te4[rk[7]>>0]<<8
1008         icm     $t1,4,0($i1)            # Te4[rk[7]>>8]<<16
1009         icm     $t1,8,0($i2)            # Te4[rk[7]>>16]<<24
1010         icm     $t1,1,0($i3)            # Te4[rk[7]>>24]
1011         x       $t1,256($t3,$tbl)       # rcon[i]
1012         xr      $s0,$t1                 # rk[8]=rk[0]^...
1013         xr      $s1,$s0                 # rk[9]=rk[1]^rk[8]
1014         xr      $s2,$s1                 # rk[10]=rk[2]^rk[9]
1015         xr      $s3,$s2                 # rk[11]=rk[3]^rk[10]
1016         st      $s0,32($key)
1017         st      $s1,36($key)
1018         st      $s2,40($key)
1019         st      $s3,44($key)
1020         brct    $rounds,.L256_continue
1021         lghi    $t0,14
1022         lghi    %r2,0
1023         lm${g}  %r4,%r13,4*$SIZE_T($sp)
1024         br      $ra
1025
1026 .align  16
1027 .L256_continue:
1028         lgr     $t1,$s3                 # temp=rk[11]
1029         srlg    $i1,$s3,8
1030         srlg    $i2,$s3,16
1031         srlg    $i3,$s3,24
1032         nr      $t1,$mask
1033         nr      $i1,$mask
1034         nr      $i2,$mask
1035         la      $t1,0($t1,$tbl)
1036         la      $i1,0($i1,$tbl)
1037         la      $i2,0($i2,$tbl)
1038         la      $i3,0($i3,$tbl)
1039         llgc    $t1,0($t1)              # Te4[rk[11]>>0]
1040         icm     $t1,2,0($i1)            # Te4[rk[11]>>8]<<8
1041         icm     $t1,4,0($i2)            # Te4[rk[11]>>16]<<16
1042         icm     $t1,8,0($i3)            # Te4[rk[11]>>24]<<24
1043         x       $t1,16($key)            # rk[12]=rk[4]^...
1044         st      $t1,48($key)
1045         x       $t1,20($key)            # rk[13]=rk[5]^rk[12]
1046         st      $t1,52($key)
1047         x       $t1,24($key)            # rk[14]=rk[6]^rk[13]
1048         st      $t1,56($key)
1049         x       $t1,28($key)            # rk[15]=rk[7]^rk[14]
1050         st      $t1,60($key)
1051
1052         srlg    $i1,$t1,8
1053         srlg    $i2,$t1,16
1054         srlg    $i3,$t1,24
1055         nr      $t1,$mask
1056         nr      $i1,$mask
1057         nr      $i2,$mask
1058
1059         la      $key,32($key)           # key+=8
1060         la      $t3,4($t3)              # i++
1061         j       .L256_loop
1062
1063 .Lminus1:
1064         lghi    %r2,-1
1065         br      $ra
1066 .size   AES_set_encrypt_key,.-AES_set_encrypt_key
1067
1068 # void AES_set_decrypt_key(const unsigned char *in, int bits,
1069 #                AES_KEY *key) {
1070 .globl  AES_set_decrypt_key
1071 .type   AES_set_decrypt_key,\@function
1072 .align  16
1073 AES_set_decrypt_key:
1074         #st${g} $key,4*$SIZE_T($sp)     # I rely on AES_set_encrypt_key to
1075         st${g}  $ra,14*$SIZE_T($sp)     # save non-volatile registers and $key!
1076         bras    $ra,_s390x_AES_set_encrypt_key
1077         #l${g}  $key,4*$SIZE_T($sp)
1078         l${g}   $ra,14*$SIZE_T($sp)
1079         ltgr    %r2,%r2
1080         bnzr    $ra
1081 ___
1082 $code.=<<___ if (!$softonly);
1083         #l      $t0,240($key)
1084         lhi     $t1,16
1085         cr      $t0,$t1
1086         jl      .Lgo
1087         oill    $t0,0x80        # set "decrypt" bit
1088         st      $t0,240($key)
1089         br      $ra
1090 ___
1091 $code.=<<___;
1092 .align  16
1093 .Lgo:   lgr     $rounds,$t0     #llgf   $rounds,240($key)
1094         la      $i1,0($key)
1095         sllg    $i2,$rounds,4
1096         la      $i2,0($i2,$key)
1097         srl     $rounds,1
1098         lghi    $t1,-16
1099
1100 .align  16
1101 .Linv:  lmg     $s0,$s1,0($i1)
1102         lmg     $s2,$s3,0($i2)
1103         stmg    $s0,$s1,0($i2)
1104         stmg    $s2,$s3,0($i1)
1105         la      $i1,16($i1)
1106         la      $i2,0($t1,$i2)
1107         brct    $rounds,.Linv
1108 ___
1109 $mask80=$i1;
1110 $mask1b=$i2;
1111 $maskfe=$i3;
1112 $code.=<<___;
1113         llgf    $rounds,240($key)
1114         aghi    $rounds,-1
1115         sll     $rounds,2       # (rounds-1)*4
1116         llilh   $mask80,0x8080
1117         llilh   $mask1b,0x1b1b
1118         llilh   $maskfe,0xfefe
1119         oill    $mask80,0x8080
1120         oill    $mask1b,0x1b1b
1121         oill    $maskfe,0xfefe
1122
1123 .align  16
1124 .Lmix:  l       $s0,16($key)    # tp1
1125         lr      $s1,$s0
1126         ngr     $s1,$mask80
1127         srlg    $t1,$s1,7
1128         slr     $s1,$t1
1129         nr      $s1,$mask1b
1130         sllg    $t1,$s0,1
1131         nr      $t1,$maskfe
1132         xr      $s1,$t1         # tp2
1133
1134         lr      $s2,$s1
1135         ngr     $s2,$mask80
1136         srlg    $t1,$s2,7
1137         slr     $s2,$t1
1138         nr      $s2,$mask1b
1139         sllg    $t1,$s1,1
1140         nr      $t1,$maskfe
1141         xr      $s2,$t1         # tp4
1142
1143         lr      $s3,$s2
1144         ngr     $s3,$mask80
1145         srlg    $t1,$s3,7
1146         slr     $s3,$t1
1147         nr      $s3,$mask1b
1148         sllg    $t1,$s2,1
1149         nr      $t1,$maskfe
1150         xr      $s3,$t1         # tp8
1151
1152         xr      $s1,$s0         # tp2^tp1
1153         xr      $s2,$s0         # tp4^tp1
1154         rll     $s0,$s0,24      # = ROTATE(tp1,8)
1155         xr      $s2,$s3         # ^=tp8
1156         xr      $s0,$s1         # ^=tp2^tp1
1157         xr      $s1,$s3         # tp2^tp1^tp8
1158         xr      $s0,$s2         # ^=tp4^tp1^tp8
1159         rll     $s1,$s1,8
1160         rll     $s2,$s2,16
1161         xr      $s0,$s1         # ^= ROTATE(tp8^tp2^tp1,24)
1162         rll     $s3,$s3,24
1163         xr      $s0,$s2         # ^= ROTATE(tp8^tp4^tp1,16)
1164         xr      $s0,$s3         # ^= ROTATE(tp8,8)
1165
1166         st      $s0,16($key)
1167         la      $key,4($key)
1168         brct    $rounds,.Lmix
1169
1170         lm${g}  %r6,%r13,6*$SIZE_T($sp)# as was saved by AES_set_encrypt_key!
1171         lghi    %r2,0
1172         br      $ra
1173 .size   AES_set_decrypt_key,.-AES_set_decrypt_key
1174 ___
1175
1176 ########################################################################
1177 # void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
1178 #                     size_t length, const AES_KEY *key,
1179 #                     unsigned char *ivec, const int enc)
1180 {
1181 my $inp="%r2";
1182 my $out="%r4";  # length and out are swapped
1183 my $len="%r3";
1184 my $key="%r5";
1185 my $ivp="%r6";
1186
1187 $code.=<<___;
1188 .globl  AES_cbc_encrypt
1189 .type   AES_cbc_encrypt,\@function
1190 .align  16
1191 AES_cbc_encrypt:
1192         xgr     %r3,%r4         # flip %r3 and %r4, out and len
1193         xgr     %r4,%r3
1194         xgr     %r3,%r4
1195 ___
1196 $code.=<<___ if (!$softonly);
1197         lhi     %r0,16
1198         cl      %r0,240($key)
1199         jh      .Lcbc_software
1200
1201         lg      %r0,0($ivp)     # copy ivec
1202         lg      %r1,8($ivp)
1203         stmg    %r0,%r1,16($sp)
1204         lmg     %r0,%r1,0($key) # copy key, cover 256 bit
1205         stmg    %r0,%r1,32($sp)
1206         lmg     %r0,%r1,16($key)
1207         stmg    %r0,%r1,48($sp)
1208         l       %r0,240($key)   # load kmc code
1209         lghi    $key,15         # res=len%16, len-=res;
1210         ngr     $key,$len
1211         sl${g}r $len,$key
1212         la      %r1,16($sp)     # parameter block - ivec || key
1213         jz      .Lkmc_truncated
1214         .long   0xb92f0042      # kmc %r4,%r2
1215         brc     1,.-4           # pay attention to "partial completion"
1216         ltr     $key,$key
1217         jnz     .Lkmc_truncated
1218 .Lkmc_done:
1219         lmg     %r0,%r1,16($sp) # copy ivec to caller
1220         stg     %r0,0($ivp)
1221         stg     %r1,8($ivp)
1222         br      $ra
1223 .align  16
1224 .Lkmc_truncated:
1225         ahi     $key,-1         # it's the way it's encoded in mvc
1226         tmll    %r0,0x80
1227         jnz     .Lkmc_truncated_dec
1228         lghi    %r1,0
1229         stg     %r1,16*$SIZE_T($sp)
1230         stg     %r1,16*$SIZE_T+8($sp)
1231         bras    %r1,1f
1232         mvc     16*$SIZE_T(1,$sp),0($inp)
1233 1:      ex      $key,0(%r1)
1234         la      %r1,16($sp)     # restore parameter block
1235         la      $inp,16*$SIZE_T($sp)
1236         lghi    $len,16
1237         .long   0xb92f0042      # kmc %r4,%r2
1238         j       .Lkmc_done
1239 .align  16
1240 .Lkmc_truncated_dec:
1241         st${g}  $out,4*$SIZE_T($sp)
1242         la      $out,16*$SIZE_T($sp)
1243         lghi    $len,16
1244         .long   0xb92f0042      # kmc %r4,%r2
1245         l${g}   $out,4*$SIZE_T($sp)
1246         bras    %r1,2f
1247         mvc     0(1,$out),16*$SIZE_T($sp)
1248 2:      ex      $key,0(%r1)
1249         j       .Lkmc_done
1250 .align  16
1251 .Lcbc_software:
1252 ___
1253 $code.=<<___;
1254         stm${g} $key,$ra,5*$SIZE_T($sp)
1255         lhi     %r0,0
1256         cl      %r0,`$stdframe+$SIZE_T-4`($sp)
1257         je      .Lcbc_decrypt
1258
1259         larl    $tbl,AES_Te
1260
1261         llgf    $s0,0($ivp)
1262         llgf    $s1,4($ivp)
1263         llgf    $s2,8($ivp)
1264         llgf    $s3,12($ivp)
1265
1266         lghi    $t0,16
1267         sl${g}r $len,$t0
1268         brc     4,.Lcbc_enc_tail        # if borrow
1269 .Lcbc_enc_loop:
1270         stm${g} $inp,$out,2*$SIZE_T($sp)
1271         x       $s0,0($inp)
1272         x       $s1,4($inp)
1273         x       $s2,8($inp)
1274         x       $s3,12($inp)
1275         lgr     %r4,$key
1276
1277         bras    $ra,_s390x_AES_encrypt
1278
1279         lm${g}  $inp,$key,2*$SIZE_T($sp)
1280         st      $s0,0($out)
1281         st      $s1,4($out)
1282         st      $s2,8($out)
1283         st      $s3,12($out)
1284
1285         la      $inp,16($inp)
1286         la      $out,16($out)
1287         lghi    $t0,16
1288         lt${g}r $len,$len
1289         jz      .Lcbc_enc_done
1290         sl${g}r $len,$t0
1291         brc     4,.Lcbc_enc_tail        # if borrow
1292         j       .Lcbc_enc_loop
1293 .align  16
1294 .Lcbc_enc_done:
1295         l${g}   $ivp,6*$SIZE_T($sp)
1296         st      $s0,0($ivp)
1297         st      $s1,4($ivp)
1298         st      $s2,8($ivp)
1299         st      $s3,12($ivp)
1300
1301         lm${g}  %r7,$ra,7*$SIZE_T($sp)
1302         br      $ra
1303
1304 .align  16
1305 .Lcbc_enc_tail:
1306         aghi    $len,15
1307         lghi    $t0,0
1308         stg     $t0,16*$SIZE_T($sp)
1309         stg     $t0,16*$SIZE_T+8($sp)
1310         bras    $t1,3f
1311         mvc     16*$SIZE_T(1,$sp),0($inp)
1312 3:      ex      $len,0($t1)
1313         lghi    $len,0
1314         la      $inp,16*$SIZE_T($sp)
1315         j       .Lcbc_enc_loop
1316
1317 .align  16
1318 .Lcbc_decrypt:
1319         larl    $tbl,AES_Td
1320
1321         lg      $t0,0($ivp)
1322         lg      $t1,8($ivp)
1323         stmg    $t0,$t1,16*$SIZE_T($sp)
1324
1325 .Lcbc_dec_loop:
1326         stm${g} $inp,$out,2*$SIZE_T($sp)
1327         llgf    $s0,0($inp)
1328         llgf    $s1,4($inp)
1329         llgf    $s2,8($inp)
1330         llgf    $s3,12($inp)
1331         lgr     %r4,$key
1332
1333         bras    $ra,_s390x_AES_decrypt
1334
1335         lm${g}  $inp,$key,2*$SIZE_T($sp)
1336         sllg    $s0,$s0,32
1337         sllg    $s2,$s2,32
1338         lr      $s0,$s1
1339         lr      $s2,$s3
1340
1341         lg      $t0,0($inp)
1342         lg      $t1,8($inp)
1343         xg      $s0,16*$SIZE_T($sp)
1344         xg      $s2,16*$SIZE_T+8($sp)
1345         lghi    $s1,16
1346         sl${g}r $len,$s1
1347         brc     4,.Lcbc_dec_tail        # if borrow
1348         brc     2,.Lcbc_dec_done        # if zero
1349         stg     $s0,0($out)
1350         stg     $s2,8($out)
1351         stmg    $t0,$t1,16*$SIZE_T($sp)
1352
1353         la      $inp,16($inp)
1354         la      $out,16($out)
1355         j       .Lcbc_dec_loop
1356
1357 .Lcbc_dec_done:
1358         stg     $s0,0($out)
1359         stg     $s2,8($out)
1360 .Lcbc_dec_exit:
1361         lm${g}  %r6,$ra,6*$SIZE_T($sp)
1362         stmg    $t0,$t1,0($ivp)
1363
1364         br      $ra
1365
1366 .align  16
1367 .Lcbc_dec_tail:
1368         aghi    $len,15
1369         stg     $s0,16*$SIZE_T($sp)
1370         stg     $s2,16*$SIZE_T+8($sp)
1371         bras    $s1,4f
1372         mvc     0(1,$out),16*$SIZE_T($sp)
1373 4:      ex      $len,0($s1)
1374         j       .Lcbc_dec_exit
1375 .size   AES_cbc_encrypt,.-AES_cbc_encrypt
1376 ___
1377 }
1378 ########################################################################
1379 # void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
1380 #                     size_t blocks, const AES_KEY *key,
1381 #                     const unsigned char *ivec)
1382 {
1383 my $inp="%r2";
1384 my $out="%r4";  # blocks and out are swapped
1385 my $len="%r3";
1386 my $key="%r5";  my $iv0="%r5";
1387 my $ivp="%r6";
1388 my $fp ="%r7";
1389
1390 $code.=<<___;
1391 .globl  AES_ctr32_encrypt
1392 .type   AES_ctr32_encrypt,\@function
1393 .align  16
1394 AES_ctr32_encrypt:
1395         xgr     %r3,%r4         # flip %r3 and %r4, $out and $len
1396         xgr     %r4,%r3
1397         xgr     %r3,%r4
1398         llgfr   $len,$len       # safe in ctr32 subroutine even in 64-bit case
1399 ___
1400 $code.=<<___ if (!$softonly);
1401         l       %r0,240($key)
1402         lhi     %r1,16
1403         clr     %r0,%r1
1404         jl      .Lctr32_software
1405
1406         stm${g} %r6,$s3,6*$SIZE_T($sp)
1407
1408         slgr    $out,$inp
1409         la      %r1,0($key)     # %r1 is permanent copy of $key
1410         lg      $iv0,0($ivp)    # load ivec
1411         lg      $ivp,8($ivp)
1412
1413         # prepare and allocate stack frame at the top of 4K page
1414         # with 1K reserved for eventual signal handling
1415         lghi    $s0,-1024-256-16# guarantee at least 256-bytes buffer
1416         lghi    $s1,-4096
1417         algr    $s0,$sp
1418         lgr     $fp,$sp
1419         ngr     $s0,$s1         # align at page boundary
1420         slgr    $fp,$s0         # total buffer size
1421         lgr     $s2,$sp
1422         lghi    $s1,1024+16     # sl[g]fi is extended-immediate facility
1423         slgr    $fp,$s1         # deduct reservation to get usable buffer size
1424         # buffer size is at lest 256 and at most 3072+256-16
1425
1426         la      $sp,1024($s0)   # alloca
1427         srlg    $fp,$fp,4       # convert bytes to blocks, minimum 16
1428         st${g}  $s2,0($sp)      # back-chain
1429         st${g}  $fp,$SIZE_T($sp)
1430
1431         slgr    $len,$fp
1432         brc     1,.Lctr32_hw_switch     # not zero, no borrow
1433         algr    $fp,$len        # input is shorter than allocated buffer
1434         lghi    $len,0
1435         st${g}  $fp,$SIZE_T($sp)
1436
1437 .Lctr32_hw_switch:
1438 ___
1439 $code.=<<___ if (!$softonly && 0);# kmctr code was measured to be ~12% slower
1440         llgfr   $s0,%r0
1441         lgr     $s1,%r1
1442         larl    %r1,OPENSSL_s390xcap_P
1443         llihh   %r0,0x8000      # check if kmctr supports the function code
1444         srlg    %r0,%r0,0($s0)
1445         ng      %r0,64(%r1)     # check kmctr capability vector
1446         lgr     %r0,$s0
1447         lgr     %r1,$s1
1448         jz      .Lctr32_km_loop
1449
1450 ####### kmctr code
1451         algr    $out,$inp       # restore $out
1452         lgr     $s1,$len        # $s1 undertakes $len
1453         j       .Lctr32_kmctr_loop
1454 .align  16
1455 .Lctr32_kmctr_loop:
1456         la      $s2,16($sp)
1457         lgr     $s3,$fp
1458 .Lctr32_kmctr_prepare:
1459         stg     $iv0,0($s2)
1460         stg     $ivp,8($s2)
1461         la      $s2,16($s2)
1462         ahi     $ivp,1          # 32-bit increment, preserves upper half
1463         brct    $s3,.Lctr32_kmctr_prepare
1464
1465         #la     $inp,0($inp)    # inp
1466         sllg    $len,$fp,4      # len
1467         #la     $out,0($out)    # out
1468         la      $s2,16($sp)     # iv
1469         .long   0xb92da042      # kmctr $out,$s2,$inp
1470         brc     1,.-4           # pay attention to "partial completion"
1471
1472         slgr    $s1,$fp
1473         brc     1,.Lctr32_kmctr_loop    # not zero, no borrow
1474         algr    $fp,$s1
1475         lghi    $s1,0
1476         brc     4+1,.Lctr32_kmctr_loop  # not zero
1477
1478         l${g}   $sp,0($sp)
1479         lm${g}  %r6,$s3,6*$SIZE_T($sp)
1480         br      $ra
1481 .align  16
1482 ___
1483 $code.=<<___ if (!$softonly);
1484 .Lctr32_km_loop:
1485         la      $s2,16($sp)
1486         lgr     $s3,$fp
1487 .Lctr32_km_prepare:
1488         stg     $iv0,0($s2)
1489         stg     $ivp,8($s2)
1490         la      $s2,16($s2)
1491         ahi     $ivp,1          # 32-bit increment, preserves upper half
1492         brct    $s3,.Lctr32_km_prepare
1493
1494         la      $s0,16($sp)     # inp
1495         sllg    $s1,$fp,4       # len
1496         la      $s2,16($sp)     # out
1497         .long   0xb92e00a8      # km %r10,%r8
1498         brc     1,.-4           # pay attention to "partial completion"
1499
1500         la      $s2,16($sp)
1501         lgr     $s3,$fp
1502         slgr    $s2,$inp
1503 .Lctr32_km_xor:
1504         lg      $s0,0($inp)
1505         lg      $s1,8($inp)
1506         xg      $s0,0($s2,$inp)
1507         xg      $s1,8($s2,$inp)
1508         stg     $s0,0($out,$inp)
1509         stg     $s1,8($out,$inp)
1510         la      $inp,16($inp)
1511         brct    $s3,.Lctr32_km_xor
1512
1513         slgr    $len,$fp
1514         brc     1,.Lctr32_km_loop       # not zero, no borrow
1515         algr    $fp,$len
1516         lghi    $len,0
1517         brc     4+1,.Lctr32_km_loop     # not zero
1518
1519         l${g}   $s0,0($sp)
1520         l${g}   $s1,$SIZE_T($sp)
1521         la      $s2,16($sp)
1522 .Lctr32_km_zap:
1523         stg     $s0,0($s2)
1524         stg     $s0,8($s2)
1525         la      $s2,16($s2)
1526         brct    $s1,.Lctr32_km_zap
1527
1528         la      $sp,0($s0)
1529         lm${g}  %r6,$s3,6*$SIZE_T($sp)
1530         br      $ra
1531 .align  16
1532 .Lctr32_software:
1533 ___
1534 $code.=<<___;
1535         stm${g} $key,$ra,5*$SIZE_T($sp)
1536         sl${g}r $inp,$out
1537         larl    $tbl,AES_Te
1538         llgf    $t1,12($ivp)
1539
1540 .Lctr32_loop:
1541         stm${g} $inp,$out,2*$SIZE_T($sp)
1542         llgf    $s0,0($ivp)
1543         llgf    $s1,4($ivp)
1544         llgf    $s2,8($ivp)
1545         lgr     $s3,$t1
1546         st      $t1,16*$SIZE_T($sp)
1547         lgr     %r4,$key
1548
1549         bras    $ra,_s390x_AES_encrypt
1550
1551         lm${g}  $inp,$ivp,2*$SIZE_T($sp)
1552         llgf    $t1,16*$SIZE_T($sp)
1553         x       $s0,0($inp,$out)
1554         x       $s1,4($inp,$out)
1555         x       $s2,8($inp,$out)
1556         x       $s3,12($inp,$out)
1557         stm     $s0,$s3,0($out)
1558
1559         la      $out,16($out)
1560         ahi     $t1,1           # 32-bit increment
1561         brct    $len,.Lctr32_loop
1562
1563         lm${g}  %r6,$ra,6*$SIZE_T($sp)
1564         br      $ra
1565 .size   AES_ctr32_encrypt,.-AES_ctr32_encrypt
1566 ___
1567 }
1568
1569 ########################################################################
1570 # void AES_xts_encrypt(const unsigned char *inp, unsigned char *out,
1571 #       size_t len, const AES_KEY *key1, const AES_KEY *key2,
1572 #       const unsigned char iv[16]);
1573 #
1574 {
1575 my $inp="%r2";
1576 my $out="%r4";  # len and out are swapped
1577 my $len="%r3";
1578 my $key1="%r5"; # $i1
1579 my $key2="%r6"; # $i2
1580 my $fp="%r7";   # $i3
1581 my $tweak=16*$SIZE_T+16;        # or $stdframe-16, bottom of the frame...
1582
1583 $code.=<<___;
1584 .type   _s390x_xts_km,\@function
1585 .align  16
1586 _s390x_xts_km:
1587 ___
1588 $code.=<<___ if(1);
1589         llgfr   $s0,%r0                 # put aside the function code
1590         lghi    $s1,0x7f
1591         nr      $s1,%r0
1592         larl    %r1,OPENSSL_s390xcap_P
1593         llihh   %r0,0x8000
1594         srlg    %r0,%r0,32($s1)         # check for 32+function code
1595         ng      %r0,32(%r1)             # check km capability vector
1596         lgr     %r0,$s0                 # restore the function code
1597         la      %r1,0($key1)            # restore $key1
1598         jz      .Lxts_km_vanilla
1599
1600         lmg     $i2,$i3,$tweak($sp)     # put aside the tweak value
1601         algr    $out,$inp
1602
1603         oill    %r0,32                  # switch to xts function code
1604         aghi    $s1,-18                 #
1605         sllg    $s1,$s1,3               # (function code - 18)*8, 0 or 16
1606         la      %r1,$tweak-16($sp)
1607         slgr    %r1,$s1                 # parameter block position
1608         lmg     $s0,$s3,0($key1)        # load 256 bits of key material,
1609         stmg    $s0,$s3,0(%r1)          # and copy it to parameter block.
1610                                         # yes, it contains junk and overlaps
1611                                         # with the tweak in 128-bit case.
1612                                         # it's done to avoid conditional
1613                                         # branch.
1614         stmg    $i2,$i3,$tweak($sp)     # "re-seat" the tweak value
1615
1616         .long   0xb92e0042              # km %r4,%r2
1617         brc     1,.-4                   # pay attention to "partial completion"
1618
1619         lrvg    $s0,$tweak+0($sp)       # load the last tweak
1620         lrvg    $s1,$tweak+8($sp)
1621         stmg    %r0,%r3,$tweak-32($sp)  # wipe copy of the key
1622
1623         nill    %r0,0xffdf              # switch back to original function code
1624         la      %r1,0($key1)            # restore pointer to $key1
1625         slgr    $out,$inp
1626
1627         llgc    $len,2*$SIZE_T-1($sp)
1628         nill    $len,0x0f               # $len%=16
1629         br      $ra
1630
1631 .align  16
1632 .Lxts_km_vanilla:
1633 ___
1634 $code.=<<___;
1635         # prepare and allocate stack frame at the top of 4K page
1636         # with 1K reserved for eventual signal handling
1637         lghi    $s0,-1024-256-16# guarantee at least 256-bytes buffer
1638         lghi    $s1,-4096
1639         algr    $s0,$sp
1640         lgr     $fp,$sp
1641         ngr     $s0,$s1         # align at page boundary
1642         slgr    $fp,$s0         # total buffer size
1643         lgr     $s2,$sp
1644         lghi    $s1,1024+16     # sl[g]fi is extended-immediate facility
1645         slgr    $fp,$s1         # deduct reservation to get usable buffer size
1646         # buffer size is at lest 256 and at most 3072+256-16
1647
1648         la      $sp,1024($s0)   # alloca
1649         nill    $fp,0xfff0      # round to 16*n
1650         st${g}  $s2,0($sp)      # back-chain
1651         nill    $len,0xfff0     # redundant
1652         st${g}  $fp,$SIZE_T($sp)
1653
1654         slgr    $len,$fp
1655         brc     1,.Lxts_km_go   # not zero, no borrow
1656         algr    $fp,$len        # input is shorter than allocated buffer
1657         lghi    $len,0
1658         st${g}  $fp,$SIZE_T($sp)
1659
1660 .Lxts_km_go:
1661         lrvg    $s0,$tweak+0($s2)       # load the tweak value in little-endian
1662         lrvg    $s1,$tweak+8($s2)
1663
1664         la      $s2,16($sp)             # vector of ascending tweak values
1665         slgr    $s2,$inp
1666         srlg    $s3,$fp,4
1667         j       .Lxts_km_start
1668
1669 .Lxts_km_loop:
1670         la      $s2,16($sp)
1671         slgr    $s2,$inp
1672         srlg    $s3,$fp,4
1673 .Lxts_km_prepare:
1674         lghi    $i1,0x87
1675         srag    $i2,$s1,63              # broadcast upper bit
1676         ngr     $i1,$i2                 # rem
1677         algr    $s0,$s0
1678         alcgr   $s1,$s1
1679         xgr     $s0,$i1
1680 .Lxts_km_start:
1681         lrvgr   $i1,$s0                 # flip byte order
1682         lrvgr   $i2,$s1
1683         stg     $i1,0($s2,$inp)
1684         stg     $i2,8($s2,$inp)
1685         xg      $i1,0($inp)
1686         xg      $i2,8($inp)
1687         stg     $i1,0($out,$inp)
1688         stg     $i2,8($out,$inp)
1689         la      $inp,16($inp)
1690         brct    $s3,.Lxts_km_prepare
1691
1692         slgr    $inp,$fp                # rewind $inp
1693         la      $s2,0($out,$inp)
1694         lgr     $s3,$fp
1695         .long   0xb92e00aa              # km $s2,$s2
1696         brc     1,.-4                   # pay attention to "partial completion"
1697
1698         la      $s2,16($sp)
1699         slgr    $s2,$inp
1700         srlg    $s3,$fp,4
1701 .Lxts_km_xor:
1702         lg      $i1,0($out,$inp)
1703         lg      $i2,8($out,$inp)
1704         xg      $i1,0($s2,$inp)
1705         xg      $i2,8($s2,$inp)
1706         stg     $i1,0($out,$inp)
1707         stg     $i2,8($out,$inp)
1708         la      $inp,16($inp)
1709         brct    $s3,.Lxts_km_xor
1710
1711         slgr    $len,$fp
1712         brc     1,.Lxts_km_loop         # not zero, no borrow
1713         algr    $fp,$len
1714         lghi    $len,0
1715         brc     4+1,.Lxts_km_loop       # not zero
1716
1717         l${g}   $i1,0($sp)              # back-chain
1718         llgf    $fp,`2*$SIZE_T-4`($sp)  # bytes used
1719         la      $i2,16($sp)
1720         srlg    $fp,$fp,4
1721 .Lxts_km_zap:
1722         stg     $i1,0($i2)
1723         stg     $i1,8($i2)
1724         la      $i2,16($i2)
1725         brct    $fp,.Lxts_km_zap
1726
1727         la      $sp,0($i1)
1728         llgc    $len,2*$SIZE_T-1($i1)
1729         nill    $len,0x0f               # $len%=16
1730         bzr     $ra
1731
1732         # generate one more tweak...
1733         lghi    $i1,0x87
1734         srag    $i2,$s1,63              # broadcast upper bit
1735         ngr     $i1,$i2                 # rem
1736         algr    $s0,$s0
1737         alcgr   $s1,$s1
1738         xgr     $s0,$i1
1739
1740         ltr     $len,$len               # clear zero flag
1741         br      $ra
1742 .size   _s390x_xts_km,.-_s390x_xts_km
1743
1744 .globl  AES_xts_encrypt
1745 .type   AES_xts_encrypt,\@function
1746 .align  16
1747 AES_xts_encrypt:
1748         xgr     %r3,%r4                 # flip %r3 and %r4, $out and $len
1749         xgr     %r4,%r3
1750         xgr     %r3,%r4
1751 ___
1752 $code.=<<___ if ($SIZE_T==4);
1753         llgfr   $len,$len
1754 ___
1755 $code.=<<___;
1756         st${g}  $len,1*$SIZE_T($sp)     # save copy of $len
1757         srag    $len,$len,4             # formally wrong, because it expands
1758                                         # sign byte, but who can afford asking
1759                                         # to process more than 2^63-1 bytes?
1760                                         # I use it, because it sets condition
1761                                         # code...
1762         bcr     8,$ra                   # abort if zero (i.e. less than 16)
1763 ___
1764 $code.=<<___ if (!$softonly);
1765         llgf    %r0,240($key2)
1766         lhi     %r1,16
1767         clr     %r0,%r1
1768         jl      .Lxts_enc_software
1769
1770         st${g}  $ra,5*$SIZE_T($sp)
1771         stm${g} %r6,$s3,6*$SIZE_T($sp)
1772
1773         sllg    $len,$len,4             # $len&=~15
1774         slgr    $out,$inp
1775
1776         # generate the tweak value
1777         l${g}   $s3,$stdframe($sp)      # pointer to iv
1778         la      $s2,$tweak($sp)
1779         lmg     $s0,$s1,0($s3)
1780         lghi    $s3,16
1781         stmg    $s0,$s1,0($s2)
1782         la      %r1,0($key2)            # $key2 is not needed anymore
1783         .long   0xb92e00aa              # km $s2,$s2, generate the tweak
1784         brc     1,.-4                   # can this happen?
1785
1786         l       %r0,240($key1)
1787         la      %r1,0($key1)            # $key1 is not needed anymore
1788         bras    $ra,_s390x_xts_km
1789         jz      .Lxts_enc_km_done
1790
1791         aghi    $inp,-16                # take one step back
1792         la      $i3,0($out,$inp)        # put aside real $out
1793 .Lxts_enc_km_steal:
1794         llgc    $i1,16($inp)
1795         llgc    $i2,0($out,$inp)
1796         stc     $i1,0($out,$inp)
1797         stc     $i2,16($out,$inp)
1798         la      $inp,1($inp)
1799         brct    $len,.Lxts_enc_km_steal
1800
1801         la      $s2,0($i3)
1802         lghi    $s3,16
1803         lrvgr   $i1,$s0                 # flip byte order
1804         lrvgr   $i2,$s1
1805         xg      $i1,0($s2)
1806         xg      $i2,8($s2)
1807         stg     $i1,0($s2)
1808         stg     $i2,8($s2)
1809         .long   0xb92e00aa              # km $s2,$s2
1810         brc     1,.-4                   # can this happen?
1811         lrvgr   $i1,$s0                 # flip byte order
1812         lrvgr   $i2,$s1
1813         xg      $i1,0($i3)
1814         xg      $i2,8($i3)
1815         stg     $i1,0($i3)
1816         stg     $i2,8($i3)
1817
1818 .Lxts_enc_km_done:
1819         stg     $sp,$tweak+0($sp)       # wipe tweak
1820         stg     $sp,$tweak+8($sp)
1821         l${g}   $ra,5*$SIZE_T($sp)
1822         lm${g}  %r6,$s3,6*$SIZE_T($sp)
1823         br      $ra
1824 .align  16
1825 .Lxts_enc_software:
1826 ___
1827 $code.=<<___;
1828         stm${g} %r6,$ra,6*$SIZE_T($sp)
1829
1830         slgr    $out,$inp
1831
1832         l${g}   $s3,$stdframe($sp)      # ivp
1833         llgf    $s0,0($s3)              # load iv
1834         llgf    $s1,4($s3)
1835         llgf    $s2,8($s3)
1836         llgf    $s3,12($s3)
1837         stm${g} %r2,%r5,2*$SIZE_T($sp)
1838         la      $key,0($key2)
1839         larl    $tbl,AES_Te
1840         bras    $ra,_s390x_AES_encrypt  # generate the tweak
1841         lm${g}  %r2,%r5,2*$SIZE_T($sp)
1842         stm     $s0,$s3,$tweak($sp)     # save the tweak
1843         j       .Lxts_enc_enter
1844
1845 .align  16
1846 .Lxts_enc_loop:
1847         lrvg    $s1,$tweak+0($sp)       # load the tweak in little-endian
1848         lrvg    $s3,$tweak+8($sp)
1849         lghi    %r1,0x87
1850         srag    %r0,$s3,63              # broadcast upper bit
1851         ngr     %r1,%r0                 # rem
1852         algr    $s1,$s1
1853         alcgr   $s3,$s3
1854         xgr     $s1,%r1
1855         lrvgr   $s1,$s1                 # flip byte order
1856         lrvgr   $s3,$s3
1857         srlg    $s0,$s1,32              # smash the tweak to 4x32-bits
1858         stg     $s1,$tweak+0($sp)       # save the tweak
1859         llgfr   $s1,$s1
1860         srlg    $s2,$s3,32
1861         stg     $s3,$tweak+8($sp)
1862         llgfr   $s3,$s3
1863         la      $inp,16($inp)           # $inp+=16
1864 .Lxts_enc_enter:
1865         x       $s0,0($inp)             # ^=*($inp)
1866         x       $s1,4($inp)
1867         x       $s2,8($inp)
1868         x       $s3,12($inp)
1869         stm${g} %r2,%r3,2*$SIZE_T($sp)  # only two registers are changing
1870         la      $key,0($key1)
1871         bras    $ra,_s390x_AES_encrypt
1872         lm${g}  %r2,%r5,2*$SIZE_T($sp)
1873         x       $s0,$tweak+0($sp)       # ^=tweak
1874         x       $s1,$tweak+4($sp)
1875         x       $s2,$tweak+8($sp)
1876         x       $s3,$tweak+12($sp)
1877         st      $s0,0($out,$inp)
1878         st      $s1,4($out,$inp)
1879         st      $s2,8($out,$inp)
1880         st      $s3,12($out,$inp)
1881         brct${g}        $len,.Lxts_enc_loop
1882
1883         llgc    $len,`2*$SIZE_T-1`($sp)
1884         nill    $len,0x0f               # $len%16
1885         jz      .Lxts_enc_done
1886
1887         la      $i3,0($inp,$out)        # put aside real $out
1888 .Lxts_enc_steal:
1889         llgc    %r0,16($inp)
1890         llgc    %r1,0($out,$inp)
1891         stc     %r0,0($out,$inp)
1892         stc     %r1,16($out,$inp)
1893         la      $inp,1($inp)
1894         brct    $len,.Lxts_enc_steal
1895         la      $out,0($i3)             # restore real $out
1896
1897         # generate last tweak...
1898         lrvg    $s1,$tweak+0($sp)       # load the tweak in little-endian
1899         lrvg    $s3,$tweak+8($sp)
1900         lghi    %r1,0x87
1901         srag    %r0,$s3,63              # broadcast upper bit
1902         ngr     %r1,%r0                 # rem
1903         algr    $s1,$s1
1904         alcgr   $s3,$s3
1905         xgr     $s1,%r1
1906         lrvgr   $s1,$s1                 # flip byte order
1907         lrvgr   $s3,$s3
1908         srlg    $s0,$s1,32              # smash the tweak to 4x32-bits
1909         stg     $s1,$tweak+0($sp)       # save the tweak
1910         llgfr   $s1,$s1
1911         srlg    $s2,$s3,32
1912         stg     $s3,$tweak+8($sp)
1913         llgfr   $s3,$s3
1914
1915         x       $s0,0($out)             # ^=*(inp)|stolen cipther-text
1916         x       $s1,4($out)
1917         x       $s2,8($out)
1918         x       $s3,12($out)
1919         st${g}  $out,4*$SIZE_T($sp)
1920         la      $key,0($key1)
1921         bras    $ra,_s390x_AES_encrypt
1922         l${g}   $out,4*$SIZE_T($sp)
1923         x       $s0,`$tweak+0`($sp)     # ^=tweak
1924         x       $s1,`$tweak+4`($sp)
1925         x       $s2,`$tweak+8`($sp)
1926         x       $s3,`$tweak+12`($sp)
1927         st      $s0,0($out)
1928         st      $s1,4($out)
1929         st      $s2,8($out)
1930         st      $s3,12($out)
1931
1932 .Lxts_enc_done:
1933         stg     $sp,$tweak+0($sp)       # wipe tweak
1934         stg     $sp,$twesk+8($sp)
1935         lm${g}  %r6,$ra,6*$SIZE_T($sp)
1936         br      $ra
1937 .size   AES_xts_encrypt,.-AES_xts_encrypt
1938 ___
1939 # void AES_xts_decrypt(const unsigned char *inp, unsigned char *out,
1940 #       size_t len, const AES_KEY *key1, const AES_KEY *key2,
1941 #       const unsigned char iv[16]);
1942 #
1943 $code.=<<___;
1944 .globl  AES_xts_decrypt
1945 .type   AES_xts_decrypt,\@function
1946 .align  16
1947 AES_xts_decrypt:
1948         xgr     %r3,%r4                 # flip %r3 and %r4, $out and $len
1949         xgr     %r4,%r3
1950         xgr     %r3,%r4
1951 ___
1952 $code.=<<___ if ($SIZE_T==4);
1953         llgfr   $len,$len
1954 ___
1955 $code.=<<___;
1956         st${g}  $len,1*$SIZE_T($sp)     # save copy of $len
1957         aghi    $len,-16
1958         bcr     4,$ra                   # abort if less than zero. formally
1959                                         # wrong, because $len is unsigned,
1960                                         # but who can afford asking to
1961                                         # process more than 2^63-1 bytes?
1962         tmll    $len,0x0f
1963         jnz     .Lxts_dec_proceed
1964         aghi    $len,16
1965 .Lxts_dec_proceed:
1966 ___
1967 $code.=<<___ if (!$softonly);
1968         llgf    %r0,240($key2)
1969         lhi     %r1,16
1970         clr     %r0,%r1
1971         jl      .Lxts_dec_software
1972
1973         st${g}  $ra,5*$SIZE_T($sp)
1974         stm${g} %r6,$s3,6*$SIZE_T($sp)
1975
1976         nill    $len,0xfff0             # $len&=~15
1977         slgr    $out,$inp
1978
1979         # generate the tweak value
1980         l${g}   $s3,$stdframe($sp)      # pointer to iv
1981         la      $s2,$tweak($sp)
1982         lmg     $s0,$s1,0($s3)
1983         lghi    $s3,16
1984         stmg    $s0,$s1,0($s2)
1985         la      %r1,0($key2)            # $key2 is not needed past this point
1986         .long   0xb92e00aa              # km $s2,$s2, generate the tweak
1987         brc     1,.-4                   # can this happen?
1988
1989         l       %r0,240($key1)
1990         la      %r1,0($key1)            # $key1 is not needed anymore
1991
1992         ltgr    $len,$len
1993         jz      .Lxts_dec_km_short
1994         bras    $ra,_s390x_xts_km
1995         jz      .Lxts_dec_km_done
1996
1997         lrvgr   $s2,$s0                 # make copy in reverse byte order
1998         lrvgr   $s3,$s1
1999         j       .Lxts_dec_km_2ndtweak
2000
2001 .Lxts_dec_km_short:
2002         llgc    $len,`2*$SIZE_T-1`($sp)
2003         nill    $len,0x0f               # $len%=16
2004         lrvg    $s0,$tweak+0($sp)       # load the tweak
2005         lrvg    $s1,$tweak+8($sp)
2006         lrvgr   $s2,$s0                 # make copy in reverse byte order
2007         lrvgr   $s3,$s1
2008
2009 .Lxts_dec_km_2ndtweak:
2010         lghi    $i1,0x87
2011         srag    $i2,$s1,63              # broadcast upper bit
2012         ngr     $i1,$i2                 # rem
2013         algr    $s0,$s0
2014         alcgr   $s1,$s1
2015         xgr     $s0,$i1
2016         lrvgr   $i1,$s0                 # flip byte order
2017         lrvgr   $i2,$s1
2018
2019         xg      $i1,0($inp)
2020         xg      $i2,8($inp)
2021         stg     $i1,0($out,$inp)
2022         stg     $i2,8($out,$inp)
2023         la      $i2,0($out,$inp)
2024         lghi    $i3,16
2025         .long   0xb92e0066              # km $i2,$i2
2026         brc     1,.-4                   # can this happen?
2027         lrvgr   $i1,$s0
2028         lrvgr   $i2,$s1
2029         xg      $i1,0($out,$inp)
2030         xg      $i2,8($out,$inp)
2031         stg     $i1,0($out,$inp)
2032         stg     $i2,8($out,$inp)
2033
2034         la      $i3,0($out,$inp)        # put aside real $out
2035 .Lxts_dec_km_steal:
2036         llgc    $i1,16($inp)
2037         llgc    $i2,0($out,$inp)
2038         stc     $i1,0($out,$inp)
2039         stc     $i2,16($out,$inp)
2040         la      $inp,1($inp)
2041         brct    $len,.Lxts_dec_km_steal
2042
2043         lgr     $s0,$s2
2044         lgr     $s1,$s3
2045         xg      $s0,0($i3)
2046         xg      $s1,8($i3)
2047         stg     $s0,0($i3)
2048         stg     $s1,8($i3)
2049         la      $s0,0($i3)
2050         lghi    $s1,16
2051         .long   0xb92e0088              # km $s0,$s0
2052         brc     1,.-4                   # can this happen?
2053         xg      $s2,0($i3)
2054         xg      $s3,8($i3)
2055         stg     $s2,0($i3)
2056         stg     $s3,8($i3)
2057 .Lxts_dec_km_done:
2058         stg     $sp,$tweak+0($sp)       # wipe tweak
2059         stg     $sp,$tweak+8($sp)
2060         l${g}   $ra,5*$SIZE_T($sp)
2061         lm${g}  %r6,$s3,6*$SIZE_T($sp)
2062         br      $ra
2063 .align  16
2064 .Lxts_dec_software:
2065 ___
2066 $code.=<<___;
2067         stm${g} %r6,$ra,6*$SIZE_T($sp)
2068
2069         srlg    $len,$len,4
2070         slgr    $out,$inp
2071
2072         l${g}   $s3,$stdframe($sp)      # ivp
2073         llgf    $s0,0($s3)              # load iv
2074         llgf    $s1,4($s3)
2075         llgf    $s2,8($s3)
2076         llgf    $s3,12($s3)
2077         stm${g} %r2,%r5,2*$SIZE_T($sp)
2078         la      $key,0($key2)
2079         larl    $tbl,AES_Te
2080         bras    $ra,_s390x_AES_encrypt  # generate the tweak
2081         lm${g}  %r2,%r5,2*$SIZE_T($sp)
2082         larl    $tbl,AES_Td
2083         lt${g}r $len,$len
2084         stm     $s0,$s3,$tweak($sp)     # save the tweak
2085         jz      .Lxts_dec_short
2086         j       .Lxts_dec_enter
2087
2088 .align  16
2089 .Lxts_dec_loop:
2090         lrvg    $s1,$tweak+0($sp)       # load the tweak in little-endian
2091         lrvg    $s3,$tweak+8($sp)
2092         lghi    %r1,0x87
2093         srag    %r0,$s3,63              # broadcast upper bit
2094         ngr     %r1,%r0                 # rem
2095         algr    $s1,$s1
2096         alcgr   $s3,$s3
2097         xgr     $s1,%r1
2098         lrvgr   $s1,$s1                 # flip byte order
2099         lrvgr   $s3,$s3
2100         srlg    $s0,$s1,32              # smash the tweak to 4x32-bits
2101         stg     $s1,$tweak+0($sp)       # save the tweak
2102         llgfr   $s1,$s1
2103         srlg    $s2,$s3,32
2104         stg     $s3,$tweak+8($sp)
2105         llgfr   $s3,$s3
2106 .Lxts_dec_enter:
2107         x       $s0,0($inp)             # tweak^=*(inp)
2108         x       $s1,4($inp)
2109         x       $s2,8($inp)
2110         x       $s3,12($inp)
2111         stm${g} %r2,%r3,2*$SIZE_T($sp)  # only two registers are changing
2112         la      $key,0($key1)
2113         bras    $ra,_s390x_AES_decrypt
2114         lm${g}  %r2,%r5,2*$SIZE_T($sp)
2115         x       $s0,$tweak+0($sp)       # ^=tweak
2116         x       $s1,$tweak+4($sp)
2117         x       $s2,$tweak+8($sp)
2118         x       $s3,$tweak+12($sp)
2119         st      $s0,0($out,$inp)
2120         st      $s1,4($out,$inp)
2121         st      $s2,8($out,$inp)
2122         st      $s3,12($out,$inp)
2123         la      $inp,16($inp)
2124         brct${g}        $len,.Lxts_dec_loop
2125
2126         llgc    $len,`2*$SIZE_T-1`($sp)
2127         nill    $len,0x0f               # $len%16
2128         jz      .Lxts_dec_done
2129
2130         # generate pair of tweaks...
2131         lrvg    $s1,$tweak+0($sp)       # load the tweak in little-endian
2132         lrvg    $s3,$tweak+8($sp)
2133         lghi    %r1,0x87
2134         srag    %r0,$s3,63              # broadcast upper bit
2135         ngr     %r1,%r0                 # rem
2136         algr    $s1,$s1
2137         alcgr   $s3,$s3
2138         xgr     $s1,%r1
2139         lrvgr   $i2,$s1                 # flip byte order
2140         lrvgr   $i3,$s3
2141         stmg    $i2,$i3,$tweak($sp)     # save the 1st tweak
2142         j       .Lxts_dec_2ndtweak
2143
2144 .align  16
2145 .Lxts_dec_short:
2146         llgc    $len,`2*$SIZE_T-1`($sp)
2147         nill    $len,0x0f               # $len%16
2148         lrvg    $s1,$tweak+0($sp)       # load the tweak in little-endian
2149         lrvg    $s3,$tweak+8($sp)
2150 .Lxts_dec_2ndtweak:
2151         lghi    %r1,0x87
2152         srag    %r0,$s3,63              # broadcast upper bit
2153         ngr     %r1,%r0                 # rem
2154         algr    $s1,$s1
2155         alcgr   $s3,$s3
2156         xgr     $s1,%r1
2157         lrvgr   $s1,$s1                 # flip byte order
2158         lrvgr   $s3,$s3
2159         srlg    $s0,$s1,32              # smash the tweak to 4x32-bits
2160         stg     $s1,$tweak-16+0($sp)    # save the 2nd tweak
2161         llgfr   $s1,$s1
2162         srlg    $s2,$s3,32
2163         stg     $s3,$tweak-16+8($sp)
2164         llgfr   $s3,$s3
2165
2166         x       $s0,0($inp)             # tweak_the_2nd^=*(inp)
2167         x       $s1,4($inp)
2168         x       $s2,8($inp)
2169         x       $s3,12($inp)
2170         stm${g} %r2,%r3,2*$SIZE_T($sp)
2171         la      $key,0($key1)
2172         bras    $ra,_s390x_AES_decrypt
2173         lm${g}  %r2,%r5,2*$SIZE_T($sp)
2174         x       $s0,$tweak-16+0($sp)    # ^=tweak_the_2nd
2175         x       $s1,$tweak-16+4($sp)
2176         x       $s2,$tweak-16+8($sp)
2177         x       $s3,$tweak-16+12($sp)
2178         st      $s0,0($out,$inp)
2179         st      $s1,4($out,$inp)
2180         st      $s2,8($out,$inp)
2181         st      $s3,12($out,$inp)
2182
2183         la      $i3,0($out,$inp)        # put aside real $out
2184 .Lxts_dec_steal:
2185         llgc    %r0,16($inp)
2186         llgc    %r1,0($out,$inp)
2187         stc     %r0,0($out,$inp)
2188         stc     %r1,16($out,$inp)
2189         la      $inp,1($inp)
2190         brct    $len,.Lxts_dec_steal
2191         la      $out,0($i3)             # restore real $out
2192
2193         lm      $s0,$s3,$tweak($sp)     # load the 1st tweak
2194         x       $s0,0($out)             # tweak^=*(inp)|stolen cipher-text
2195         x       $s1,4($out)
2196         x       $s2,8($out)
2197         x       $s3,12($out)
2198         st${g}  $out,4*$SIZE_T($sp)
2199         la      $key,0($key1)
2200         bras    $ra,_s390x_AES_decrypt
2201         l${g}   $out,4*$SIZE_T($sp)
2202         x       $s0,$tweak+0($sp)       # ^=tweak
2203         x       $s1,$tweak+4($sp)
2204         x       $s2,$tweak+8($sp)
2205         x       $s3,$tweak+12($sp)
2206         st      $s0,0($out)
2207         st      $s1,4($out)
2208         st      $s2,8($out)
2209         st      $s3,12($out)
2210         stg     $sp,$tweak-16+0($sp)    # wipe 2nd tweak
2211         stg     $sp,$tweak-16+8($sp)
2212 .Lxts_dec_done:
2213         stg     $sp,$tweak+0($sp)       # wipe tweak
2214         stg     $sp,$twesk+8($sp)
2215         lm${g}  %r6,$ra,6*$SIZE_T($sp)
2216         br      $ra
2217 .size   AES_xts_decrypt,.-AES_xts_decrypt
2218 ___
2219 }
2220 $code.=<<___;
2221 .string "AES for s390x, CRYPTOGAMS by <appro\@openssl.org>"
2222 .comm   OPENSSL_s390xcap_P,80,8
2223 ___
2224
2225 $code =~ s/\`([^\`]*)\`/eval $1/gem;
2226 print $code;
2227 close STDOUT;   # force flush