1#! /usr/bin/env perl 2# Copyright 2009-2020 The OpenSSL Project Authors. All Rights Reserved. 3# 4# Licensed under the OpenSSL license (the "License"). You may not use 5# this file except in compliance with the License. You can obtain a copy 6# in the file LICENSE in the source distribution or at 7# https://www.openssl.org/source/license.html 8 9$flavour = shift; 10 11if ($flavour =~ /3[12]/) { 12 $SIZE_T=4; 13 $g=""; 14} else { 15 $SIZE_T=8; 16 $g="g"; 17} 18 19while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} 20open STDOUT,">$output"; 21 22$ra="%r14"; 23$sp="%r15"; 24$stdframe=16*$SIZE_T+4*8; 25 26$code=<<___; 27#include "s390x_arch.h" 28 29.text 30 31.globl OPENSSL_s390x_facilities 32.type OPENSSL_s390x_facilities,\@function 33.align 16 34OPENSSL_s390x_facilities: 35 lghi %r0,0 36 larl %r4,OPENSSL_s390xcap_P 37 38 stg %r0,S390X_STFLE+8(%r4) # wipe capability vectors 39 stg %r0,S390X_STFLE+16(%r4) 40 stg %r0,S390X_STFLE+24(%r4) 41 stg %r0,S390X_KIMD(%r4) 42 stg %r0,S390X_KIMD+8(%r4) 43 stg %r0,S390X_KLMD(%r4) 44 stg %r0,S390X_KLMD+8(%r4) 45 stg %r0,S390X_KM(%r4) 46 stg %r0,S390X_KM+8(%r4) 47 stg %r0,S390X_KMC(%r4) 48 stg %r0,S390X_KMC+8(%r4) 49 stg %r0,S390X_KMAC(%r4) 50 stg %r0,S390X_KMAC+8(%r4) 51 stg %r0,S390X_KMCTR(%r4) 52 stg %r0,S390X_KMCTR+8(%r4) 53 stg %r0,S390X_KMO(%r4) 54 stg %r0,S390X_KMO+8(%r4) 55 stg %r0,S390X_KMF(%r4) 56 stg %r0,S390X_KMF+8(%r4) 57 stg %r0,S390X_PRNO(%r4) 58 stg %r0,S390X_PRNO+8(%r4) 59 stg %r0,S390X_KMA(%r4) 60 stg %r0,S390X_KMA+8(%r4) 61 62 .long 0xb2b04000 # stfle 0(%r4) 63 brc 8,.Ldone 64 lghi %r0,1 65 .long 0xb2b04000 # stfle 0(%r4) 66 brc 8,.Ldone 67 lghi %r0,2 68 .long 0xb2b04000 # stfle 0(%r4) 69.Ldone: 70 lmg %r2,%r3,S390X_STFLE(%r4) 71 tmhl %r2,0x4000 # check for message-security-assist 72 jz .Lret 73 74 lghi %r0,S390X_QUERY # query kimd capabilities 75 la %r1,S390X_KIMD(%r4) 76 .long 0xb93e0002 # kimd %r0,%r2 77 78 lghi %r0,S390X_QUERY # query klmd capabilities 79 la %r1,S390X_KLMD(%r4) 80 .long 0xb93f0002 # klmd %r0,%r2 81 82 lghi %r0,S390X_QUERY # query km capability vector 83 la %r1,S390X_KM(%r4) 84 .long 0xb92e0042 # km %r4,%r2 85 86 lghi %r0,S390X_QUERY # query kmc capability vector 87 la %r1,S390X_KMC(%r4) 88 .long 0xb92f0042 # kmc %r4,%r2 89 90 lghi %r0,S390X_QUERY # query kmac capability vector 91 la %r1,S390X_KMAC(%r4) 92 .long 0xb91e0042 # kmac %r4,%r2 93 94 tmhh %r3,0x0004 # check for message-security-assist-4 95 jz .Lret 96 97 lghi %r0,S390X_QUERY # query kmctr capability vector 98 la %r1,S390X_KMCTR(%r4) 99 .long 0xb92d2042 # kmctr %r4,%r2,%r2 100 101 lghi %r0,S390X_QUERY # query kmo capability vector 102 la %r1,S390X_KMO(%r4) 103 .long 0xb92b0042 # kmo %r4,%r2 104 105 lghi %r0,S390X_QUERY # query kmf capability vector 106 la %r1,S390X_KMF(%r4) 107 .long 0xb92a0042 # kmf %r4,%r2 108 109 tml %r2,0x40 # check for message-security-assist-5 110 jz .Lret 111 112 lghi %r0,S390X_QUERY # query prno capability vector 113 la %r1,S390X_PRNO(%r4) 114 .long 0xb93c0042 # prno %r4,%r2 115 116 lg %r2,S390X_STFLE+16(%r4) 117 tmhl %r2,0x2000 # check for message-security-assist-8 118 jz .Lret 119 120 lghi %r0,S390X_QUERY # query kma capability vector 121 la %r1,S390X_KMA(%r4) 122 .long 0xb9294022 # kma %r2,%r4,%r2 123 124.Lret: 125 br $ra 126.size OPENSSL_s390x_facilities,.-OPENSSL_s390x_facilities 127 128.globl OPENSSL_rdtsc 129.type OPENSSL_rdtsc,\@function 130.align 16 131OPENSSL_rdtsc: 132 larl %r4,OPENSSL_s390xcap_P 133 tm S390X_STFLE+3(%r4),0x40 # check for store-clock-fast facility 134 jz .Lstck 135 136 .long 0xb27cf010 # stckf 16($sp) 137 lg %r2,16($sp) 138 br $ra 139.Lstck: 140 stck 16($sp) 141 lg %r2,16($sp) 142 br $ra 143.size OPENSSL_rdtsc,.-OPENSSL_rdtsc 144 145.globl OPENSSL_atomic_add 146.type OPENSSL_atomic_add,\@function 147.align 16 148OPENSSL_atomic_add: 149 l %r1,0(%r2) 150.Lspin: lr %r0,%r1 151 ar %r0,%r3 152 cs %r1,%r0,0(%r2) 153 brc 4,.Lspin 154 lgfr %r2,%r0 # OpenSSL expects the new value 155 br $ra 156.size OPENSSL_atomic_add,.-OPENSSL_atomic_add 157 158.globl OPENSSL_wipe_cpu 159.type OPENSSL_wipe_cpu,\@function 160.align 16 161OPENSSL_wipe_cpu: 162 xgr %r0,%r0 163 xgr %r1,%r1 164 lgr %r2,$sp 165 xgr %r3,%r3 166 xgr %r4,%r4 167 lzdr %f0 168 lzdr %f1 169 lzdr %f2 170 lzdr %f3 171 lzdr %f4 172 lzdr %f5 173 lzdr %f6 174 lzdr %f7 175 br $ra 176.size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu 177 178.globl OPENSSL_cleanse 179.type OPENSSL_cleanse,\@function 180.align 16 181OPENSSL_cleanse: 182#if !defined(__s390x__) && !defined(__s390x) 183 llgfr %r3,%r3 184#endif 185 lghi %r4,15 186 lghi %r0,0 187 clgr %r3,%r4 188 jh .Lot 189 clgr %r3,%r0 190 bcr 8,%r14 191.Little: 192 stc %r0,0(%r2) 193 la %r2,1(%r2) 194 brctg %r3,.Little 195 br %r14 196.align 4 197.Lot: tmll %r2,7 198 jz .Laligned 199 stc %r0,0(%r2) 200 la %r2,1(%r2) 201 brctg %r3,.Lot 202.Laligned: 203 srlg %r4,%r3,3 204.Loop: stg %r0,0(%r2) 205 la %r2,8(%r2) 206 brctg %r4,.Loop 207 lghi %r4,7 208 ngr %r3,%r4 209 jnz .Little 210 br $ra 211.size OPENSSL_cleanse,.-OPENSSL_cleanse 212 213.globl CRYPTO_memcmp 214.type CRYPTO_memcmp,\@function 215.align 16 216CRYPTO_memcmp: 217#if !defined(__s390x__) && !defined(__s390x) 218 llgfr %r4,%r4 219#endif 220 lghi %r5,0 221 clgr %r4,%r5 222 je .Lno_data 223 224.Loop_cmp: 225 llgc %r0,0(%r2) 226 la %r2,1(%r2) 227 llgc %r1,0(%r3) 228 la %r3,1(%r3) 229 xr %r1,%r0 230 or %r5,%r1 231 brctg %r4,.Loop_cmp 232 233 lnr %r5,%r5 234 srl %r5,31 235.Lno_data: 236 lgr %r2,%r5 237 br $ra 238.size CRYPTO_memcmp,.-CRYPTO_memcmp 239 240.globl OPENSSL_instrument_bus 241.type OPENSSL_instrument_bus,\@function 242.align 16 243OPENSSL_instrument_bus: 244 lghi %r2,0 245 br %r14 246.size OPENSSL_instrument_bus,.-OPENSSL_instrument_bus 247 248.globl OPENSSL_instrument_bus2 249.type OPENSSL_instrument_bus2,\@function 250.align 16 251OPENSSL_instrument_bus2: 252 lghi %r2,0 253 br $ra 254.size OPENSSL_instrument_bus2,.-OPENSSL_instrument_bus2 255 256.globl OPENSSL_vx_probe 257.type OPENSSL_vx_probe,\@function 258.align 16 259OPENSSL_vx_probe: 260 .word 0xe700,0x0000,0x0044 # vzero %v0 261 br $ra 262.size OPENSSL_vx_probe,.-OPENSSL_vx_probe 263___ 264 265{ 266################ 267# void s390x_kimd(const unsigned char *in, size_t len, unsigned int fc, 268# void *param) 269my ($in,$len,$fc,$param) = map("%r$_",(2..5)); 270$code.=<<___; 271.globl s390x_kimd 272.type s390x_kimd,\@function 273.align 16 274s390x_kimd: 275 llgfr %r0,$fc 276 lgr %r1,$param 277 278 .long 0xb93e0002 # kimd %r0,%r2 279 brc 1,.-4 # pay attention to "partial completion" 280 281 br $ra 282.size s390x_kimd,.-s390x_kimd 283___ 284} 285 286{ 287################ 288# void s390x_klmd(const unsigned char *in, size_t inlen, unsigned char *out, 289# size_t outlen, unsigned int fc, void *param) 290my ($in,$inlen,$out,$outlen,$fc) = map("%r$_",(2..6)); 291$code.=<<___; 292.globl s390x_klmd 293.type s390x_klmd,\@function 294.align 32 295s390x_klmd: 296 llgfr %r0,$fc 297 l${g} %r1,$stdframe($sp) 298 299 .long 0xb93f0042 # klmd %r4,%r2 300 brc 1,.-4 # pay attention to "partial completion" 301 302 br $ra 303.size s390x_klmd,.-s390x_klmd 304___ 305} 306 307################ 308# void s390x_km(const unsigned char *in, size_t len, unsigned char *out, 309# unsigned int fc, void *param) 310{ 311my ($in,$len,$out,$fc,$param) = map("%r$_",(2..6)); 312$code.=<<___; 313.globl s390x_km 314.type s390x_km,\@function 315.align 16 316s390x_km: 317 lr %r0,$fc 318 l${g}r %r1,$param 319 320 .long 0xb92e0042 # km $out,$in 321 brc 1,.-4 # pay attention to "partial completion" 322 323 br $ra 324.size s390x_km,.-s390x_km 325___ 326} 327 328################ 329# void s390x_kmac(const unsigned char *in, size_t len, unsigned int fc, 330# void *param) 331{ 332my ($in,$len,$fc,$param) = map("%r$_",(2..5)); 333$code.=<<___; 334.globl s390x_kmac 335.type s390x_kmac,\@function 336.align 16 337s390x_kmac: 338 lr %r0,$fc 339 l${g}r %r1,$param 340 341 .long 0xb91e0002 # kmac %r0,$in 342 brc 1,.-4 # pay attention to "partial completion" 343 344 br $ra 345.size s390x_kmac,.-s390x_kmac 346___ 347} 348 349################ 350# void s390x_kmo(const unsigned char *in, size_t len, unsigned char *out, 351# unsigned int fc, void *param) 352{ 353my ($in,$len,$out,$fc,$param) = map("%r$_",(2..6)); 354$code.=<<___; 355.globl s390x_kmo 356.type s390x_kmo,\@function 357.align 16 358s390x_kmo: 359 lr %r0,$fc 360 l${g}r %r1,$param 361 362 .long 0xb92b0042 # kmo $out,$in 363 brc 1,.-4 # pay attention to "partial completion" 364 365 br $ra 366.size s390x_kmo,.-s390x_kmo 367___ 368} 369 370################ 371# void s390x_kmf(const unsigned char *in, size_t len, unsigned char *out, 372# unsigned int fc, void *param) 373{ 374my ($in,$len,$out,$fc,$param) = map("%r$_",(2..6)); 375$code.=<<___; 376.globl s390x_kmf 377.type s390x_kmf,\@function 378.align 16 379s390x_kmf: 380 lr %r0,$fc 381 l${g}r %r1,$param 382 383 .long 0xb92a0042 # kmf $out,$in 384 brc 1,.-4 # pay attention to "partial completion" 385 386 br $ra 387.size s390x_kmf,.-s390x_kmf 388___ 389} 390 391################ 392# void s390x_kma(const unsigned char *aad, size_t alen, 393# const unsigned char *in, size_t len, 394# unsigned char *out, unsigned int fc, void *param) 395{ 396my ($aad,$alen,$in,$len,$out) = map("%r$_",(2..6)); 397$code.=<<___; 398.globl s390x_kma 399.type s390x_kma,\@function 400.align 16 401s390x_kma: 402 st${g} $out,6*$SIZE_T($sp) 403 lm${g} %r0,%r1,$stdframe($sp) 404 405 .long 0xb9292064 # kma $out,$aad,$in 406 brc 1,.-4 # pay attention to "partial completion" 407 408 l${g} $out,6*$SIZE_T($sp) 409 br $ra 410.size s390x_kma,.-s390x_kma 411___ 412} 413 414$code.=<<___; 415.section .init 416 brasl $ra,OPENSSL_cpuid_setup 417___ 418 419$code =~ s/\`([^\`]*)\`/eval $1/gem; 420print $code; 421close STDOUT or die "error closing STDOUT: $!"; # force flush 422