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