38e18b2452bbc2062c2aa6f41de285e0344f1eba
[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 key lengthes 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.
56
57 while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
58 open STDOUT,">$output";
59
60 $softonly=0;    # allow hardware support
61
62 $t0="%r0";      $mask="%r0";
63 $t1="%r1";
64 $t2="%r2";      $inp="%r2";
65 $t3="%r3";      $out="%r3";     $bits="%r3";
66 $key="%r4";
67 $i1="%r5";
68 $i2="%r6";
69 $i3="%r7";
70 $s0="%r8";
71 $s1="%r9";
72 $s2="%r10";
73 $s3="%r11";
74 $tbl="%r12";
75 $rounds="%r13";
76 $ra="%r14";
77 $sp="%r15";
78
79 sub _data_word()
80 { my $i;
81     while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; }
82 }
83
84 $code=<<___;
85 .text
86
87 .type   AES_Te,\@object
88 .align  256
89 AES_Te:
90 ___
91 &_data_word(
92         0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
93         0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
94         0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
95         0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
96         0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
97         0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
98         0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
99         0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
100         0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
101         0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
102         0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
103         0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
104         0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
105         0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
106         0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
107         0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
108         0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
109         0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
110         0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
111         0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
112         0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
113         0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
114         0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
115         0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
116         0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
117         0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
118         0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
119         0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
120         0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
121         0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
122         0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
123         0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
124         0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
125         0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
126         0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
127         0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
128         0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
129         0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
130         0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
131         0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
132         0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
133         0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
134         0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
135         0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
136         0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
137         0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
138         0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
139         0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
140         0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
141         0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
142         0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
143         0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
144         0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
145         0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
146         0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
147         0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
148         0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
149         0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
150         0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
151         0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
152         0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
153         0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
154         0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
155         0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a);
156 $code.=<<___;
157 # Te4[256]
158 .byte   0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5
159 .byte   0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76
160 .byte   0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0
161 .byte   0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0
162 .byte   0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc
163 .byte   0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15
164 .byte   0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a
165 .byte   0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75
166 .byte   0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0
167 .byte   0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84
168 .byte   0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b
169 .byte   0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf
170 .byte   0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85
171 .byte   0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8
172 .byte   0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
173 .byte   0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2
174 .byte   0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17
175 .byte   0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73
176 .byte   0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88
177 .byte   0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb
178 .byte   0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c
179 .byte   0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79
180 .byte   0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9
181 .byte   0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08
182 .byte   0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6
183 .byte   0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a
184 .byte   0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e
185 .byte   0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e
186 .byte   0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94
187 .byte   0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf
188 .byte   0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68
189 .byte   0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
190 # rcon[]
191 .long   0x01000000, 0x02000000, 0x04000000, 0x08000000
192 .long   0x10000000, 0x20000000, 0x40000000, 0x80000000
193 .long   0x1B000000, 0x36000000, 0, 0, 0, 0, 0, 0
194 .align  256
195 .size   AES_Te,.-AES_Te
196
197 # void AES_encrypt(const unsigned char *inp, unsigned char *out,
198 #                const AES_KEY *key) {
199 .globl  AES_encrypt
200 .type   AES_encrypt,\@function
201 AES_encrypt:
202 ___
203 $code.=<<___ if (!$softonly);
204         l       %r0,240($key)
205         lhi     %r1,16
206         clr     %r0,%r1
207         jl      .Lesoft
208
209         la      %r1,0($key)
210         #la     %r2,0($inp)
211         la      %r4,0($out)
212         lghi    %r3,16          # single block length
213         .long   0xb92e0042      # km %r4,%r2
214         brc     1,.-4           # can this happen?
215         br      %r14
216 .align  64
217 .Lesoft:
218 ___
219 $code.=<<___;
220         stmg    %r3,$ra,24($sp)
221
222         llgf    $s0,0($inp)
223         llgf    $s1,4($inp)
224         llgf    $s2,8($inp)
225         llgf    $s3,12($inp)
226
227         larl    $tbl,AES_Te
228         bras    $ra,_s390x_AES_encrypt
229
230         lg      $out,24($sp)
231         st      $s0,0($out)
232         st      $s1,4($out)
233         st      $s2,8($out)
234         st      $s3,12($out)
235
236         lmg     %r6,$ra,48($sp)
237         br      $ra
238 .size   AES_encrypt,.-AES_encrypt
239
240 .type   _s390x_AES_encrypt,\@function
241 .align  16
242 _s390x_AES_encrypt:
243         stg     $ra,152($sp)
244         x       $s0,0($key)
245         x       $s1,4($key)
246         x       $s2,8($key)
247         x       $s3,12($key)
248         l       $rounds,240($key)
249         llill   $mask,`0xff<<3`
250         aghi    $rounds,-1
251         j       .Lenc_loop
252 .align  16
253 .Lenc_loop:
254         sllg    $t1,$s0,`0+3`
255         srlg    $t2,$s0,`8-3`
256         srlg    $t3,$s0,`16-3`
257         srl     $s0,`24-3`
258         nr      $s0,$mask
259         ngr     $t1,$mask
260         nr      $t2,$mask
261         nr      $t3,$mask
262
263         srlg    $i1,$s1,`16-3`  # i0
264         sllg    $i2,$s1,`0+3`
265         srlg    $i3,$s1,`8-3`
266         srl     $s1,`24-3`
267         nr      $i1,$mask
268         nr      $s1,$mask
269         ngr     $i2,$mask
270         nr      $i3,$mask
271
272         l       $s0,0($s0,$tbl) # Te0[s0>>24]
273         l       $t1,1($t1,$tbl) # Te3[s0>>0]
274         l       $t2,2($t2,$tbl) # Te2[s0>>8]
275         l       $t3,3($t3,$tbl) # Te1[s0>>16]
276
277         x       $s0,3($i1,$tbl) # Te1[s1>>16]
278         l       $s1,0($s1,$tbl) # Te0[s1>>24]
279         x       $t2,1($i2,$tbl) # Te3[s1>>0]
280         x       $t3,2($i3,$tbl) # Te2[s1>>8]
281
282         srlg    $i1,$s2,`8-3`   # i0
283         srlg    $i2,$s2,`16-3`  # i1
284         nr      $i1,$mask
285         nr      $i2,$mask
286         sllg    $i3,$s2,`0+3`
287         srl     $s2,`24-3`
288         nr      $s2,$mask
289         ngr     $i3,$mask
290
291         xr      $s1,$t1
292         srlg    $ra,$s3,`8-3`   # i1
293         sllg    $t1,$s3,`0+3`   # i0
294         nr      $ra,$mask
295         la      $key,16($key)
296         ngr     $t1,$mask
297
298         x       $s0,2($i1,$tbl) # Te2[s2>>8]
299         x       $s1,3($i2,$tbl) # Te1[s2>>16]
300         l       $s2,0($s2,$tbl) # Te0[s2>>24]
301         x       $t3,1($i3,$tbl) # Te3[s2>>0]
302
303         srlg    $i3,$s3,`16-3`  # i2
304         xr      $s2,$t2
305         srl     $s3,`24-3`
306         nr      $i3,$mask
307         nr      $s3,$mask
308
309         x       $s0,0($key)
310         x       $s1,4($key)
311         x       $s2,8($key)
312         x       $t3,12($key)
313
314         x       $s0,1($t1,$tbl) # Te3[s3>>0]
315         x       $s1,2($ra,$tbl) # Te2[s3>>8]
316         x       $s2,3($i3,$tbl) # Te1[s3>>16]
317         l       $s3,0($s3,$tbl) # Te0[s3>>24]
318         xr      $s3,$t3
319
320         brct    $rounds,.Lenc_loop
321         .align  16
322
323         sllg    $t1,$s0,`0+3`
324         srlg    $t2,$s0,`8-3`
325         ngr     $t1,$mask
326         srlg    $t3,$s0,`16-3`
327         srl     $s0,`24-3`
328         nr      $s0,$mask
329         nr      $t2,$mask
330         nr      $t3,$mask
331
332         srlg    $i1,$s1,`16-3`  # i0
333         sllg    $i2,$s1,`0+3`
334         ngr     $i2,$mask
335         srlg    $i3,$s1,`8-3`
336         srl     $s1,`24-3`
337         nr      $i1,$mask
338         nr      $s1,$mask
339         nr      $i3,$mask
340
341         llgc    $s0,2($s0,$tbl) # Te4[s0>>24]
342         llgc    $t1,2($t1,$tbl) # Te4[s0>>0]
343         sll     $s0,24
344         llgc    $t2,2($t2,$tbl) # Te4[s0>>8]
345         llgc    $t3,2($t3,$tbl) # Te4[s0>>16]
346         sll     $t2,8
347         sll     $t3,16
348
349         llgc    $i1,2($i1,$tbl) # Te4[s1>>16]
350         llgc    $s1,2($s1,$tbl) # Te4[s1>>24]
351         llgc    $i2,2($i2,$tbl) # Te4[s1>>0]
352         llgc    $i3,2($i3,$tbl) # Te4[s1>>8]
353         sll     $i1,16
354         sll     $s1,24
355         sll     $i3,8
356         or      $s0,$i1
357         or      $s1,$t1
358         or      $t2,$i2
359         or      $t3,$i3
360         
361         srlg    $i1,$s2,`8-3`   # i0
362         srlg    $i2,$s2,`16-3`  # i1
363         nr      $i1,$mask
364         nr      $i2,$mask
365         sllg    $i3,$s2,`0+3`
366         srl     $s2,`24-3`
367         ngr     $i3,$mask
368         nr      $s2,$mask
369
370         sllg    $t1,$s3,`0+3`   # i0
371         srlg    $ra,$s3,`8-3`   # i1
372         ngr     $t1,$mask
373
374         llgc    $i1,2($i1,$tbl) # Te4[s2>>8]
375         llgc    $i2,2($i2,$tbl) # Te4[s2>>16]
376         sll     $i1,8
377         llgc    $s2,2($s2,$tbl) # Te4[s2>>24]
378         llgc    $i3,2($i3,$tbl) # Te4[s2>>0]
379         sll     $i2,16
380         nr      $ra,$mask
381         sll     $s2,24
382         or      $s0,$i1
383         or      $s1,$i2
384         or      $s2,$t2
385         or      $t3,$i3
386
387         srlg    $i3,$s3,`16-3`  # i2
388         srl     $s3,`24-3`
389         nr      $i3,$mask
390         nr      $s3,$mask
391
392         l       $t0,16($key)
393         l       $t2,20($key)
394
395         llgc    $i1,2($t1,$tbl) # Te4[s3>>0]
396         llgc    $i2,2($ra,$tbl) # Te4[s3>>8]
397         llgc    $i3,2($i3,$tbl) # Te4[s3>>16]
398         llgc    $s3,2($s3,$tbl) # Te4[s3>>24]
399         sll     $i2,8
400         sll     $i3,16
401         sll     $s3,24
402         or      $s0,$i1
403         or      $s1,$i2
404         or      $s2,$i3
405         or      $s3,$t3
406
407         lg      $ra,152($sp)
408         xr      $s0,$t0
409         xr      $s1,$t2
410         x       $s2,24($key)
411         x       $s3,28($key)
412
413         br      $ra     
414 .size   _s390x_AES_encrypt,.-_s390x_AES_encrypt
415 ___
416
417 $code.=<<___;
418 .type   AES_Td,\@object
419 .align  256
420 AES_Td:
421 ___
422 &_data_word(
423         0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
424         0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
425         0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
426         0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
427         0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
428         0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
429         0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
430         0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
431         0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
432         0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
433         0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
434         0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
435         0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
436         0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
437         0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
438         0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
439         0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
440         0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
441         0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
442         0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
443         0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
444         0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
445         0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
446         0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
447         0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
448         0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
449         0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
450         0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
451         0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
452         0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
453         0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
454         0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
455         0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
456         0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
457         0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
458         0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
459         0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
460         0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
461         0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
462         0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
463         0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
464         0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
465         0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
466         0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
467         0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
468         0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
469         0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
470         0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
471         0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
472         0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
473         0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
474         0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
475         0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
476         0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
477         0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
478         0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
479         0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
480         0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
481         0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
482         0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
483         0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
484         0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
485         0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
486         0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742);
487 $code.=<<___;
488 # Td4[256]
489 .byte   0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38
490 .byte   0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
491 .byte   0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87
492 .byte   0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
493 .byte   0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d
494 .byte   0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
495 .byte   0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2
496 .byte   0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
497 .byte   0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16
498 .byte   0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
499 .byte   0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda
500 .byte   0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
501 .byte   0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a
502 .byte   0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
503 .byte   0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02
504 .byte   0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
505 .byte   0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea
506 .byte   0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
507 .byte   0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85
508 .byte   0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
509 .byte   0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89
510 .byte   0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
511 .byte   0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20
512 .byte   0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
513 .byte   0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31
514 .byte   0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
515 .byte   0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d
516 .byte   0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
517 .byte   0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0
518 .byte   0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
519 .byte   0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26
520 .byte   0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
521 .size   AES_Td,.-AES_Td
522
523 # void AES_decrypt(const unsigned char *inp, unsigned char *out,
524 #                const AES_KEY *key) {
525 .globl  AES_decrypt
526 .type   AES_decrypt,\@function
527 AES_decrypt:
528 ___
529 $code.=<<___ if (!$softonly);
530         l       %r0,240($key)
531         lhi     %r1,16
532         clr     %r0,%r1
533         jl      .Ldsoft
534
535         la      %r1,0($key)
536         #la     %r2,0($inp)
537         la      %r4,0($out)
538         lghi    %r3,16          # single block length
539         .long   0xb92e0042      # km %r4,%r2
540         brc     1,.-4           # can this happen?
541         br      %r14
542 .align  64
543 .Ldsoft:
544 ___
545 $code.=<<___;
546         stmg    %r3,$ra,24($sp)
547
548         llgf    $s0,0($inp)
549         llgf    $s1,4($inp)
550         llgf    $s2,8($inp)
551         llgf    $s3,12($inp)
552
553         larl    $tbl,AES_Td
554         bras    $ra,_s390x_AES_decrypt
555
556         lg      $out,24($sp)
557         st      $s0,0($out)
558         st      $s1,4($out)
559         st      $s2,8($out)
560         st      $s3,12($out)
561
562         lmg     %r6,$ra,48($sp)
563         br      $ra
564 .size   AES_decrypt,.-AES_decrypt
565
566 .type   _s390x_AES_decrypt,\@function
567 .align  16
568 _s390x_AES_decrypt:
569         stg     $ra,152($sp)
570         x       $s0,0($key)
571         x       $s1,4($key)
572         x       $s2,8($key)
573         x       $s3,12($key)
574         l       $rounds,240($key)
575         llill   $mask,`0xff<<3`
576         aghi    $rounds,-1
577         j       .Ldec_loop
578 .align  16
579 .Ldec_loop:
580         srlg    $t1,$s0,`16-3`
581         srlg    $t2,$s0,`8-3`
582         sllg    $t3,$s0,`0+3`
583         srl     $s0,`24-3`
584         nr      $s0,$mask
585         nr      $t1,$mask
586         nr      $t2,$mask
587         ngr     $t3,$mask
588
589         sllg    $i1,$s1,`0+3`   # i0
590         srlg    $i2,$s1,`16-3`
591         srlg    $i3,$s1,`8-3`
592         srl     $s1,`24-3`
593         ngr     $i1,$mask
594         nr      $s1,$mask
595         nr      $i2,$mask
596         nr      $i3,$mask
597
598         l       $s0,0($s0,$tbl) # Td0[s0>>24]
599         l       $t1,3($t1,$tbl) # Td1[s0>>16]
600         l       $t2,2($t2,$tbl) # Td2[s0>>8]
601         l       $t3,1($t3,$tbl) # Td3[s0>>0]
602
603         x       $s0,1($i1,$tbl) # Td3[s1>>0]
604         l       $s1,0($s1,$tbl) # Td0[s1>>24]
605         x       $t2,3($i2,$tbl) # Td1[s1>>16]
606         x       $t3,2($i3,$tbl) # Td2[s1>>8]
607
608         srlg    $i1,$s2,`8-3`   # i0
609         sllg    $i2,$s2,`0+3`   # i1
610         srlg    $i3,$s2,`16-3`
611         srl     $s2,`24-3`
612         nr      $i1,$mask
613         ngr     $i2,$mask
614         nr      $s2,$mask
615         nr      $i3,$mask
616
617         xr      $s1,$t1
618         srlg    $ra,$s3,`8-3`   # i1
619         srlg    $t1,$s3,`16-3`  # i0
620         nr      $ra,$mask
621         la      $key,16($key)
622         nr      $t1,$mask
623
624         x       $s0,2($i1,$tbl) # Td2[s2>>8]
625         x       $s1,1($i2,$tbl) # Td3[s2>>0]
626         l       $s2,0($s2,$tbl) # Td0[s2>>24]
627         x       $t3,3($i3,$tbl) # Td1[s2>>16]
628
629         sllg    $i3,$s3,`0+3`   # i2
630         srl     $s3,`24-3`
631         ngr     $i3,$mask
632         nr      $s3,$mask
633
634         xr      $s2,$t2
635         x       $s0,0($key)
636         x       $s1,4($key)
637         x       $s2,8($key)
638         x       $t3,12($key)
639
640         x       $s0,3($t1,$tbl) # Td1[s3>>16]
641         x       $s1,2($ra,$tbl) # Td2[s3>>8]
642         x       $s2,1($i3,$tbl) # Td3[s3>>0]
643         l       $s3,0($s3,$tbl) # Td0[s3>>24]
644         xr      $s3,$t3
645
646         brct    $rounds,.Ldec_loop
647         .align  16
648
649         l       $t1,`2048+0`($tbl)      # prefetch Td4
650         l       $t2,`2048+64`($tbl)
651         l       $t3,`2048+128`($tbl)
652         l       $i1,`2048+192`($tbl)
653         llill   $mask,0xff
654
655         srlg    $i3,$s0,24      # i0
656         srlg    $t1,$s0,16
657         srlg    $t2,$s0,8
658         nr      $s0,$mask       # i3
659         nr      $t1,$mask
660
661         srlg    $i1,$s1,24
662         nr      $t2,$mask
663         srlg    $i2,$s1,16
664         srlg    $ra,$s1,8
665         nr      $s1,$mask       # i0
666         nr      $i2,$mask
667         nr      $ra,$mask
668
669         llgc    $i3,2048($i3,$tbl)      # Td4[s0>>24]
670         llgc    $t1,2048($t1,$tbl)      # Td4[s0>>16]
671         llgc    $t2,2048($t2,$tbl)      # Td4[s0>>8]
672         sll     $t1,16
673         llgc    $t3,2048($s0,$tbl)      # Td4[s0>>0]
674         sllg    $s0,$i3,24
675         sll     $t2,8
676
677         llgc    $s1,2048($s1,$tbl)      # Td4[s1>>0]
678         llgc    $i1,2048($i1,$tbl)      # Td4[s1>>24]
679         llgc    $i2,2048($i2,$tbl)      # Td4[s1>>16]
680         sll     $i1,24
681         llgc    $i3,2048($ra,$tbl)      # Td4[s1>>8]
682         sll     $i2,16
683         sll     $i3,8
684         or      $s0,$s1
685         or      $t1,$i1
686         or      $t2,$i2
687         or      $t3,$i3
688
689         srlg    $i1,$s2,8       # i0
690         srlg    $i2,$s2,24
691         srlg    $i3,$s2,16
692         nr      $s2,$mask       # i1
693         nr      $i1,$mask
694         nr      $i3,$mask
695         llgc    $i1,2048($i1,$tbl)      # Td4[s2>>8]
696         llgc    $s1,2048($s2,$tbl)      # Td4[s2>>0]
697         llgc    $i2,2048($i2,$tbl)      # Td4[s2>>24]
698         llgc    $i3,2048($i3,$tbl)      # Td4[s2>>16]
699         sll     $i1,8
700         sll     $i2,24
701         or      $s0,$i1
702         sll     $i3,16
703         or      $t2,$i2
704         or      $t3,$i3
705
706         srlg    $i1,$s3,16      # i0
707         srlg    $i2,$s3,8       # i1
708         srlg    $i3,$s3,24
709         nr      $s3,$mask       # i2
710         nr      $i1,$mask
711         nr      $i2,$mask
712
713         lg      $ra,152($sp)
714         or      $s1,$t1
715         l       $t0,16($key)
716         l       $t1,20($key)
717
718         llgc    $i1,2048($i1,$tbl)      # Td4[s3>>16]
719         llgc    $i2,2048($i2,$tbl)      # Td4[s3>>8]
720         sll     $i1,16
721         llgc    $s2,2048($s3,$tbl)      # Td4[s3>>0]
722         llgc    $s3,2048($i3,$tbl)      # Td4[s3>>24]
723         sll     $i2,8
724         sll     $s3,24
725         or      $s0,$i1
726         or      $s1,$i2
727         or      $s2,$t2
728         or      $s3,$t3
729
730         xr      $s0,$t0
731         xr      $s1,$t1
732         x       $s2,24($key)
733         x       $s3,28($key)
734
735         br      $ra     
736 .size   _s390x_AES_decrypt,.-_s390x_AES_decrypt
737 ___
738
739 $code.=<<___;
740 # void AES_set_encrypt_key(const unsigned char *in, int bits,
741 #                AES_KEY *key) {
742 .globl  AES_set_encrypt_key
743 .type   AES_set_encrypt_key,\@function
744 .align  16
745 AES_set_encrypt_key:
746         lghi    $t0,0
747         clgr    $inp,$t0
748         je      .Lminus1
749         clgr    $key,$t0
750         je      .Lminus1
751
752         lghi    $t0,128
753         clr     $bits,$t0
754         je      .Lproceed
755         lghi    $t0,192
756         clr     $bits,$t0
757         je      .Lproceed
758         lghi    $t0,256
759         clr     $bits,$t0
760         je      .Lproceed
761         lghi    %r2,-2
762         br      %r14
763
764 .align  16
765 .Lproceed:
766 ___
767 $code.=<<___ if (!$softonly);
768         # convert bits to km code, [128,192,256]->[18,19,20]
769         lhi     %r5,-128
770         lhi     %r0,18
771         ar      %r5,$bits
772         srl     %r5,6
773         ar      %r5,%r0
774
775         larl    %r1,OPENSSL_s390xcap_P
776         lg      %r0,0(%r1)
777         tmhl    %r0,0x4000      # check for message-security assist
778         jz      .Lekey_internal
779
780         lghi    %r0,0           # query capability vector
781         la      %r1,16($sp)
782         .long   0xb92f0042      # kmc %r4,%r2
783
784         llihh   %r1,0x8000
785         srlg    %r1,%r1,0(%r5)
786         ng      %r1,16($sp)
787         jz      .Lekey_internal
788
789         lmg     %r0,%r1,0($inp) # just copy 128 bits...
790         stmg    %r0,%r1,0($key)
791         lhi     %r0,192
792         cr      $bits,%r0
793         jl      1f
794         lg      %r1,16($inp)
795         stg     %r1,16($key)
796         je      1f
797         lg      %r1,24($inp)
798         stg     %r1,24($key)
799 1:      st      $bits,236($key) # save bits
800         st      %r5,240($key)   # save km code
801         lghi    %r2,0
802         br      %r14
803 ___
804 $code.=<<___;
805 .align  16
806 .Lekey_internal:
807         stmg    %r6,%r13,48($sp)        # all non-volatile regs
808
809         larl    $tbl,AES_Te+2048
810
811         llgf    $s0,0($inp)
812         llgf    $s1,4($inp)
813         llgf    $s2,8($inp)
814         llgf    $s3,12($inp)
815         st      $s0,0($key)
816         st      $s1,4($key)
817         st      $s2,8($key)
818         st      $s3,12($key)
819         lghi    $t0,128
820         cr      $bits,$t0
821         jne     .Lnot128
822
823         llill   $mask,0xff
824         lghi    $t3,0                   # i=0
825         lghi    $rounds,10
826         st      $rounds,240($key)
827
828         llgfr   $t2,$s3                 # temp=rk[3]
829         srlg    $i1,$s3,8
830         srlg    $i2,$s3,16
831         srlg    $i3,$s3,24
832         nr      $t2,$mask
833         nr      $i1,$mask
834         nr      $i2,$mask
835
836 .align  16
837 .L128_loop:
838         la      $t2,0($t2,$tbl)
839         la      $i1,0($i1,$tbl)
840         la      $i2,0($i2,$tbl)
841         la      $i3,0($i3,$tbl)
842         icm     $t2,2,0($t2)            # Te4[rk[3]>>0]<<8
843         icm     $t2,4,0($i1)            # Te4[rk[3]>>8]<<16
844         icm     $t2,8,0($i2)            # Te4[rk[3]>>16]<<24
845         icm     $t2,1,0($i3)            # Te4[rk[3]>>24]
846         x       $t2,256($t3,$tbl)       # rcon[i]
847         xr      $s0,$t2                 # rk[4]=rk[0]^...
848         xr      $s1,$s0                 # rk[5]=rk[1]^rk[4]
849         xr      $s2,$s1                 # rk[6]=rk[2]^rk[5]
850         xr      $s3,$s2                 # rk[7]=rk[3]^rk[6]
851
852         llgfr   $t2,$s3                 # temp=rk[3]
853         srlg    $i1,$s3,8
854         srlg    $i2,$s3,16
855         nr      $t2,$mask
856         nr      $i1,$mask
857         srlg    $i3,$s3,24
858         nr      $i2,$mask
859
860         st      $s0,16($key)
861         st      $s1,20($key)
862         st      $s2,24($key)
863         st      $s3,28($key)
864         la      $key,16($key)           # key+=4
865         la      $t3,4($t3)              # i++
866         brct    $rounds,.L128_loop
867         lghi    %r2,0
868         lmg     %r6,%r13,48($sp)
869         br      $ra
870
871 .align  16
872 .Lnot128:
873         llgf    $t0,16($inp)
874         llgf    $t1,20($inp)
875         st      $t0,16($key)
876         st      $t1,20($key)
877         lghi    $t0,192
878         cr      $bits,$t0
879         jne     .Lnot192
880
881         llill   $mask,0xff
882         lghi    $t3,0                   # i=0
883         lghi    $rounds,12
884         st      $rounds,240($key)
885         lghi    $rounds,8
886
887         srlg    $i1,$t1,8
888         srlg    $i2,$t1,16
889         srlg    $i3,$t1,24
890         nr      $t1,$mask
891         nr      $i1,$mask
892         nr      $i2,$mask
893
894 .align  16
895 .L192_loop:
896         la      $t1,0($t1,$tbl)
897         la      $i1,0($i1,$tbl)
898         la      $i2,0($i2,$tbl)
899         la      $i3,0($i3,$tbl)
900         icm     $t1,2,0($t1)            # Te4[rk[5]>>0]<<8
901         icm     $t1,4,0($i1)            # Te4[rk[5]>>8]<<16
902         icm     $t1,8,0($i2)            # Te4[rk[5]>>16]<<24
903         icm     $t1,1,0($i3)            # Te4[rk[5]>>24]
904         x       $t1,256($t3,$tbl)       # rcon[i]
905         xr      $s0,$t1                 # rk[6]=rk[0]^...
906         xr      $s1,$s0                 # rk[7]=rk[1]^rk[6]
907         xr      $s2,$s1                 # rk[8]=rk[2]^rk[7]
908         xr      $s3,$s2                 # rk[9]=rk[3]^rk[8]
909
910         st      $s0,24($key)
911         st      $s1,28($key)
912         st      $s2,32($key)
913         st      $s3,36($key)
914         brct    $rounds,.L192_continue
915         lghi    %r2,0
916         lmg     %r6,%r13,48($sp)
917         br      $ra
918
919 .align  16
920 .L192_continue:
921         lgr     $t1,$s3
922         x       $t1,16($key)            # rk[10]=rk[4]^rk[9]
923         st      $t1,40($key)
924         x       $t1,20($key)            # rk[11]=rk[5]^rk[10]
925         st      $t1,44($key)
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         la      $key,24($key)           # key+=6
935         la      $t3,4($t3)              # i++
936         j       .L192_loop
937
938 .align  16
939 .Lnot192:
940         llgf    $t0,24($inp)
941         llgf    $t1,28($inp)
942         st      $t0,24($key)
943         st      $t1,28($key)
944         llill   $mask,0xff
945         lghi    $t3,0                   # i=0
946         lghi    $rounds,14
947         st      $rounds,240($key)
948         lghi    $rounds,7
949
950         srlg    $i1,$t1,8
951         srlg    $i2,$t1,16
952         srlg    $i3,$t1,24
953         nr      $t1,$mask
954         nr      $i1,$mask
955         nr      $i2,$mask
956
957 .align  16
958 .L256_loop:
959         la      $t1,0($t1,$tbl)
960         la      $i1,0($i1,$tbl)
961         la      $i2,0($i2,$tbl)
962         la      $i3,0($i3,$tbl)
963         icm     $t1,2,0($t1)            # Te4[rk[7]>>0]<<8
964         icm     $t1,4,0($i1)            # Te4[rk[7]>>8]<<16
965         icm     $t1,8,0($i2)            # Te4[rk[7]>>16]<<24
966         icm     $t1,1,0($i3)            # Te4[rk[7]>>24]
967         x       $t1,256($t3,$tbl)       # rcon[i]
968         xr      $s0,$t1                 # rk[8]=rk[0]^...
969         xr      $s1,$s0                 # rk[9]=rk[1]^rk[8]
970         xr      $s2,$s1                 # rk[10]=rk[2]^rk[9]
971         xr      $s3,$s2                 # rk[11]=rk[3]^rk[10]
972         st      $s0,32($key)
973         st      $s1,36($key)
974         st      $s2,40($key)
975         st      $s3,44($key)
976         brct    $rounds,.L256_continue
977         lghi    %r2,0
978         lmg     %r6,%r13,48($sp)
979         br      $ra
980
981 .align  16
982 .L256_continue:
983         lgr     $t1,$s3                 # temp=rk[11]
984         srlg    $i1,$s3,8
985         srlg    $i2,$s3,16
986         srlg    $i3,$s3,24
987         nr      $t1,$mask
988         nr      $i1,$mask
989         nr      $i2,$mask
990         la      $t1,0($t1,$tbl)
991         la      $i1,0($i1,$tbl)
992         la      $i2,0($i2,$tbl)
993         la      $i3,0($i3,$tbl)
994         llgc    $t1,0($t1)              # Te4[rk[11]>>0]
995         icm     $t1,2,0($i1)            # Te4[rk[11]>>8]<<8
996         icm     $t1,4,0($i2)            # Te4[rk[11]>>16]<<16
997         icm     $t1,8,0($i3)            # Te4[rk[11]>>24]<<24
998         x       $t1,16($key)            # rk[12]=rk[4]^...
999         st      $t1,48($key)
1000         x       $t1,20($key)            # rk[13]=rk[5]^rk[12]
1001         st      $t1,52($key)
1002         x       $t1,24($key)            # rk[14]=rk[6]^rk[13]
1003         st      $t1,56($key)
1004         x       $t1,28($key)            # rk[15]=rk[7]^rk[14]
1005         st      $t1,60($key)
1006
1007         srlg    $i1,$t1,8
1008         srlg    $i2,$t1,16
1009         srlg    $i3,$t1,24
1010         nr      $t1,$mask
1011         nr      $i1,$mask
1012         nr      $i2,$mask
1013
1014         la      $key,32($key)           # key+=8
1015         la      $t3,4($t3)              # i++
1016         j       .L256_loop
1017
1018 .Lminus1:
1019         lghi    %r2,-1
1020         br      $ra
1021 .size   AES_set_encrypt_key,.-AES_set_encrypt_key
1022
1023 # void AES_set_decrypt_key(const unsigned char *in, int bits,
1024 #                AES_KEY *key) {
1025 .globl  AES_set_decrypt_key
1026 .type   AES_set_decrypt_key,\@function
1027 .align  16
1028 AES_set_decrypt_key:
1029         stg     $key,32($sp)            # I rely on AES_set_encrypt_key to
1030         stg     $ra,112($sp)            # save non-volatile registers!
1031         bras    $ra,AES_set_encrypt_key
1032         lg      $key,32($sp)
1033         lg      $ra,112($sp)
1034         ltgr    %r2,%r2
1035         bnzr    $ra
1036 ___
1037 $code.=<<___ if (!$softonly);
1038         l       $t0,240($key)
1039         lhi     $t1,16
1040         cr      $t0,$t1
1041         jl      .Lgo
1042         oill    $t0,0x80        # set "decrypt" bit
1043         st      $t0,240($key)
1044         br      $ra
1045
1046 .align  16
1047 .Ldkey_internal:
1048         stg     $key,32($sp)
1049         stg     $ra,40($sp)
1050         bras    $ra,.Lekey_internal
1051         lg      $key,32($sp)
1052         lg      $ra,40($sp)
1053 ___
1054 $code.=<<___;
1055
1056 .Lgo:   llgf    $rounds,240($key)
1057         la      $i1,0($key)
1058         sllg    $i2,$rounds,4
1059         la      $i2,0($i2,$key)
1060         srl     $rounds,1
1061         lghi    $t1,-16
1062
1063 .align  16
1064 .Linv:  lmg     $s0,$s1,0($i1)
1065         lmg     $s2,$s3,0($i2)
1066         stmg    $s0,$s1,0($i2)
1067         stmg    $s2,$s3,0($i1)
1068         la      $i1,16($i1)
1069         la      $i2,0($t1,$i2)
1070         brct    $rounds,.Linv
1071 ___
1072 $mask80=$i1;
1073 $mask1b=$i2;
1074 $maskfe=$i3;
1075 $code.=<<___;
1076         llgf    $rounds,240($key)
1077         aghi    $rounds,-1
1078         sll     $rounds,2       # (rounds-1)*4
1079         llilh   $mask80,0x8080
1080         llilh   $mask1b,0x1b1b
1081         llilh   $maskfe,0xfefe
1082         oill    $mask80,0x8080
1083         oill    $mask1b,0x1b1b
1084         oill    $maskfe,0xfefe
1085
1086 .align  16
1087 .Lmix:  l       $s0,16($key)    # tp1
1088         lr      $s1,$s0
1089         ngr     $s1,$mask80
1090         srlg    $t1,$s1,7
1091         slr     $s1,$t1
1092         nr      $s1,$mask1b
1093         sllg    $t1,$s0,1
1094         nr      $t1,$maskfe
1095         xr      $s1,$t1         # tp2
1096
1097         lr      $s2,$s1
1098         ngr     $s2,$mask80
1099         srlg    $t1,$s2,7
1100         slr     $s2,$t1
1101         nr      $s2,$mask1b
1102         sllg    $t1,$s1,1
1103         nr      $t1,$maskfe
1104         xr      $s2,$t1         # tp4
1105
1106         lr      $s3,$s2
1107         ngr     $s3,$mask80
1108         srlg    $t1,$s3,7
1109         slr     $s3,$t1
1110         nr      $s3,$mask1b
1111         sllg    $t1,$s2,1
1112         nr      $t1,$maskfe
1113         xr      $s3,$t1         # tp8
1114
1115         xr      $s1,$s0         # tp2^tp1
1116         xr      $s2,$s0         # tp4^tp1
1117         rll     $s0,$s0,24      # = ROTATE(tp1,8)
1118         xr      $s2,$s3         # ^=tp8
1119         xr      $s0,$s1         # ^=tp2^tp1
1120         xr      $s1,$s3         # tp2^tp1^tp8
1121         xr      $s0,$s2         # ^=tp4^tp1^tp8
1122         rll     $s1,$s1,8
1123         rll     $s2,$s2,16
1124         xr      $s0,$s1         # ^= ROTATE(tp8^tp2^tp1,24)
1125         rll     $s3,$s3,24
1126         xr      $s0,$s2         # ^= ROTATE(tp8^tp4^tp1,16)
1127         xr      $s0,$s3         # ^= ROTATE(tp8,8)
1128
1129         st      $s0,16($key)
1130         la      $key,4($key)
1131         brct    $rounds,.Lmix
1132
1133         lmg     %r6,%r13,48($sp)# as was saved by AES_set_encrypt_key!
1134         lghi    %r2,0
1135         br      $ra
1136 .size   AES_set_decrypt_key,.-AES_set_decrypt_key
1137 ___
1138
1139 #void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
1140 #                     size_t length, const AES_KEY *key,
1141 #                     unsigned char *ivec, const int enc)
1142 {
1143 my $inp="%r2";
1144 my $out="%r4";  # length and out are swapped
1145 my $len="%r3";
1146 my $key="%r5";
1147 my $ivp="%r6";
1148
1149 $code.=<<___;
1150 .globl  AES_cbc_encrypt
1151 .type   AES_cbc_encrypt,\@function
1152 .align  16
1153 AES_cbc_encrypt:
1154         xgr     %r3,%r4         # flip %r3 and %r4, out and len
1155         xgr     %r4,%r3
1156         xgr     %r3,%r4
1157 ___
1158 $code.=<<___ if (!$softonly);
1159         lhi     %r0,16
1160         cl      %r0,240($key)
1161         jh      .Lcbc_software
1162
1163         lg      %r0,0($ivp)     # copy ivec
1164         lg      %r1,8($ivp)
1165         stmg    %r0,%r1,16($sp)
1166         lmg     %r0,%r1,0($key) # copy key, cover 256 bit
1167         stmg    %r0,%r1,32($sp)
1168         lmg     %r0,%r1,16($key)
1169         stmg    %r0,%r1,48($sp)
1170         l       %r0,240($key)   # load kmc code
1171         lghi    $key,15         # res=len%16, len-=res;
1172         ngr     $key,$len
1173         slgr    $len,$key
1174         la      %r1,16($sp)     # parameter block - ivec || key
1175         jz      .Lkmc_truncated
1176         .long   0xb92f0042      # kmc %r4,%r2
1177         brc     1,.-4           # pay attention to "partial completion"
1178         ltr     $key,$key
1179         jnz     .Lkmc_truncated
1180 .Lkmc_done:
1181         lmg     %r0,%r1,16($sp) # copy ivec to caller
1182         stg     %r0,0($ivp)
1183         stg     %r1,8($ivp)
1184         br      $ra
1185 .align  16
1186 .Lkmc_truncated:
1187         ahi     $key,-1         # it's the way it's encoded in mvc
1188         tmll    %r0,0x80
1189         jnz     .Lkmc_truncated_dec
1190         lghi    %r1,0
1191         stg     %r1,128($sp)
1192         stg     %r1,136($sp)
1193         bras    %r1,1f
1194         mvc     128(1,$sp),0($inp)
1195 1:      ex      $key,0(%r1)
1196         la      %r1,16($sp)     # restore parameter block
1197         la      $inp,128($sp)
1198         lghi    $len,16
1199         .long   0xb92f0042      # kmc %r4,%r2
1200         j       .Lkmc_done
1201 .align  16
1202 .Lkmc_truncated_dec:
1203         stg     $out,64($sp)
1204         la      $out,128($sp)
1205         lghi    $len,16
1206         .long   0xb92f0042      # kmc %r4,%r2
1207         lg      $out,64($sp)
1208         bras    %r1,2f
1209         mvc     0(1,$out),128($sp)
1210 2:      ex      $key,0(%r1)
1211         j       .Lkmc_done
1212 .align  16
1213 .Lcbc_software:
1214 ___
1215 $code.=<<___;
1216         stmg    $key,$ra,40($sp)
1217         lhi     %r0,0
1218         cl      %r0,164($sp)
1219         je      .Lcbc_decrypt
1220
1221         larl    $tbl,AES_Te
1222
1223         llgf    $s0,0($ivp)
1224         llgf    $s1,4($ivp)
1225         llgf    $s2,8($ivp)
1226         llgf    $s3,12($ivp)
1227
1228         lghi    $t0,16
1229         slgr    $len,$t0
1230         brc     4,.Lcbc_enc_tail        # if borrow
1231 .Lcbc_enc_loop:
1232         stmg    $inp,$out,16($sp)
1233         x       $s0,0($inp)
1234         x       $s1,4($inp)
1235         x       $s2,8($inp)
1236         x       $s3,12($inp)
1237         lgr     %r4,$key
1238
1239         bras    $ra,_s390x_AES_encrypt
1240
1241         lmg     $inp,$key,16($sp)
1242         st      $s0,0($out)
1243         st      $s1,4($out)
1244         st      $s2,8($out)
1245         st      $s3,12($out)
1246
1247         la      $inp,16($inp)
1248         la      $out,16($out)
1249         lghi    $t0,16
1250         ltgr    $len,$len
1251         jz      .Lcbc_enc_done
1252         slgr    $len,$t0
1253         brc     4,.Lcbc_enc_tail        # if borrow
1254         j       .Lcbc_enc_loop
1255 .align  16
1256 .Lcbc_enc_done:
1257         lg      $ivp,48($sp)
1258         st      $s0,0($ivp)
1259         st      $s1,4($ivp)     
1260         st      $s2,8($ivp)
1261         st      $s3,12($ivp)
1262
1263         lmg     %r7,$ra,56($sp)
1264         br      $ra
1265
1266 .align  16
1267 .Lcbc_enc_tail:
1268         aghi    $len,15
1269         lghi    $t0,0
1270         stg     $t0,128($sp)
1271         stg     $t0,136($sp)
1272         bras    $t1,3f
1273         mvc     128(1,$sp),0($inp)
1274 3:      ex      $len,0($t1)
1275         lghi    $len,0
1276         la      $inp,128($sp)
1277         j       .Lcbc_enc_loop
1278
1279 .align  16
1280 .Lcbc_decrypt:
1281         larl    $tbl,AES_Td
1282
1283         lg      $t0,0($ivp)
1284         lg      $t1,8($ivp)
1285         stmg    $t0,$t1,128($sp)
1286
1287 .Lcbc_dec_loop:
1288         stmg    $inp,$out,16($sp)
1289         llgf    $s0,0($inp)
1290         llgf    $s1,4($inp)
1291         llgf    $s2,8($inp)
1292         llgf    $s3,12($inp)
1293         lgr     %r4,$key
1294
1295         bras    $ra,_s390x_AES_decrypt
1296
1297         lmg     $inp,$key,16($sp)
1298         sllg    $s0,$s0,32
1299         sllg    $s2,$s2,32
1300         lr      $s0,$s1
1301         lr      $s2,$s3
1302
1303         lg      $t0,0($inp)
1304         lg      $t1,8($inp)
1305         xg      $s0,128($sp)
1306         xg      $s2,136($sp)
1307         lghi    $s1,16
1308         slgr    $len,$s1
1309         brc     4,.Lcbc_dec_tail        # if borrow
1310         brc     2,.Lcbc_dec_done        # if zero
1311         stg     $s0,0($out)
1312         stg     $s2,8($out)
1313         stmg    $t0,$t1,128($sp)
1314
1315         la      $inp,16($inp)
1316         la      $out,16($out)
1317         j       .Lcbc_dec_loop
1318
1319 .Lcbc_dec_done:
1320         stg     $s0,0($out)
1321         stg     $s2,8($out)
1322 .Lcbc_dec_exit:
1323         lmg     $ivp,$ra,48($sp)
1324         stmg    $t0,$t1,0($ivp)
1325
1326         br      $ra
1327
1328 .align  16
1329 .Lcbc_dec_tail:
1330         aghi    $len,15
1331         stg     $s0,128($sp)
1332         stg     $s2,136($sp)
1333         bras    $s1,4f
1334         mvc     0(1,$out),128($sp)
1335 4:      ex      $len,0($s1)
1336         j       .Lcbc_dec_exit
1337 .size   AES_cbc_encrypt,.-AES_cbc_encrypt
1338 ___
1339 }
1340 #void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
1341 #                     size_t blocks, const AES_KEY *key,
1342 #                     const unsigned char *ivec)
1343 {
1344 my $inp="%r2";
1345 my $out="%r3";
1346 my $len="%r4";
1347 my $key="%r5";  my $iv0="%r5";
1348 my $ivp="%r6";
1349 my $fp ="%r7";
1350
1351 $code.=<<___;
1352 .globl  AES_ctr32_encrypt
1353 .type   AES_ctr32_encrypt,\@function
1354 .align  16
1355 AES_ctr32_encrypt:
1356 ___
1357 $code.=<<___ if (!$softonly);
1358         l       %r0,240($key)
1359         lhi     %r1,16
1360         clr     %r0,%r1
1361         jl      .Lctr32_software
1362
1363         stmg    %r6,$s3,48($sp)
1364
1365         slgr    $out,$inp
1366         la      %r1,0($key)     # %r1 is permanent copy of $key
1367         lg      $iv0,0($ivp)    # load ivec
1368         lg      $ivp,8($ivp)
1369
1370         # prepare and allocate stack frame
1371         lghi    $s0,-272        # guarantee at least 256-bytes buffer
1372         lghi    $s1,-4096
1373         lgr     $fp,$sp
1374         algr    $s0,$sp
1375         ngr     $s0,$s1         # align at page boundary
1376         la      $sp,0($s0)      # alloca
1377         stg     $fp,0($s0)      # back-chain
1378
1379         # calculate resultant buffer size
1380         la      $s0,16($s0)     # buffer starts at offset of 16
1381         slgr    $fp,$s0
1382         srlg    $fp,$fp,4       # $fp is buffer length in blocks, minimum 16
1383         stg     $fp,8($sp)
1384
1385         slgr    $len,$fp
1386         brc     1,.Lctr32_hw_loop       # not zero, no borrow
1387         algr    $fp,$len
1388         lghi    $len,0
1389         stg     $fp,8($sp)
1390
1391 .Lctr32_hw_loop:
1392         la      $s2,16($sp)
1393         lgr     $s3,$fp
1394 .Lctr32_hw_prepare:
1395         stg     $iv0,0($s2)
1396         stg     $ivp,8($s2)
1397         la      $s2,16($s2)
1398         ahi     $ivp,1          # 32-bit increment, preserves upper half
1399         brct    $s3,.Lctr32_hw_prepare
1400
1401         la      $s0,16($sp)     # inp
1402         sllg    $s1,$fp,4       # len
1403         la      $s2,16($sp)     # out
1404         .long   0xb92e00a8      # km %r10,%r8
1405         brc     1,.-4           # pay attention to "partial completion"
1406
1407         la      $s2,16($sp)
1408         lgr     $s3,$fp
1409         slgr    $s2,$inp
1410 .Lctr32_hw_xor:
1411         lg      $s0,0($inp)
1412         lg      $s1,8($inp)
1413         xg      $s0,0($s2,$inp)
1414         xg      $s1,8($s2,$inp)
1415         stg     $s0,0($out,$inp)
1416         stg     $s1,8($out,$inp)
1417         la      $inp,16($inp)
1418         brct    $s3,.Lctr32_hw_xor
1419
1420         slgr    $len,$fp
1421         brc     1,.Lctr32_hw_loop       # not zero, no borrow
1422         algr    $fp,$len
1423         lghi    $len,0
1424         brc     4+1,.Lctr32_hw_loop     # not zero
1425
1426         lg      $s0,0($sp)
1427         lg      $s1,8($sp)
1428         la      $s2,16($sp)
1429 .Lctr32_hw_zap:
1430         stg     $s0,0($s2)
1431         stg     $s0,8($s2)
1432         la      $s2,16($s2)
1433         brct    $s1,.Lctr32_hw_zap
1434
1435         la      $sp,0($s0)
1436         lmg     %r6,$s3,48($sp)
1437         br      $ra
1438 .align  16
1439 .Lctr32_software:
1440 ___
1441 $code.=<<___;
1442         stmg    $key,$ra,40($sp)
1443         slgr    $out,$inp
1444         larl    $tbl,AES_Te
1445         llgf    $t1,12($ivp)
1446
1447 .Lctr32_loop:
1448         stmg    $inp,$len,16($sp)
1449         llgf    $s0,0($ivp)
1450         llgf    $s1,4($ivp)
1451         llgf    $s2,8($ivp)
1452         lgr     $s3,$t1
1453         st      $t1,128($sp)
1454         lgr     %r4,$key
1455
1456         bras    $ra,_s390x_AES_encrypt
1457
1458         lmg     $inp,$ivp,16($sp)
1459         llgf    $t1,128($sp)
1460         x       $s0,0($inp)
1461         x       $s1,4($inp)
1462         x       $s2,8($inp)
1463         x       $s3,12($inp)
1464         st      $s0,0($out,$inp)
1465         st      $s1,4($out,$inp)
1466         st      $s2,8($out,$inp)
1467         st      $s3,12($out,$inp)
1468
1469         la      $inp,16($inp)
1470         ahi     $t1,1           # 32-bit increment
1471         brct    $len,.Lctr32_loop
1472
1473         lmg     %r6,$ra,48($sp)
1474         br      $ra
1475 .size   AES_ctr32_encrypt,.-AES_ctr32_encrypt
1476 ___
1477 }
1478 $code.=<<___;
1479 .comm  OPENSSL_s390xcap_P,8,8
1480 .string "AES for s390x, CRYPTOGAMS by <appro\@openssl.org>"
1481 ___
1482
1483 $code =~ s/\`([^\`]*)\`/eval $1/gem;
1484 print $code;
1485 close STDOUT;   # force flush