From 9c59438dadc2b8026c058deb0759da78de1bb7ba Mon Sep 17 00:00:00 2001 From: Patrick Steuer Date: Fri, 10 Feb 2017 19:43:08 +0100 Subject: [PATCH 06/44] s390x assembly pack: extended s390x capability vector (STFLE). Extended the s390x capability vector to store the longer facility list available from z13 onwards. The bits indicating the vector extensions are set to zero, if the kernel does not enable the vector facility. Signed-off-by: Patrick Steuer --- crypto/aes/asm/aes-s390x.pl | 10 +++++----- crypto/modes/asm/ghash-s390x.pl | 4 ++-- crypto/s390x_arch.h | 9 +++++++-- crypto/s390xcap.c | 31 +++++++++++++++++++++++++++++++ crypto/s390xcpuid.S | 14 +++++++++----- crypto/sha/asm/sha1-s390x.pl | 4 ++-- crypto/sha/asm/sha512-s390x.pl | 4 ++-- 7 files changed, 58 insertions(+), 18 deletions(-) Index: openssl-1.1.0g/crypto/aes/asm/aes-s390x.pl =================================================================== --- openssl-1.1.0g.orig/crypto/aes/asm/aes-s390x.pl 2018-01-10 17:13:05.962202226 +0100 +++ openssl-1.1.0g/crypto/aes/asm/aes-s390x.pl 2018-01-10 17:22:31.466891754 +0100 @@ -823,8 +823,8 @@ $code.=<<___ if (!$softonly); larl %r1,OPENSSL_s390xcap_P llihh %r0,0x8000 srlg %r0,%r0,0(%r5) - ng %r0,32(%r1) # check availability of both km... - ng %r0,48(%r1) # ...and kmc support for given key length + ng %r0,40(%r1) # check availability of both km... + ng %r0,56(%r1) # ...and kmc support for given key length jz .Lekey_internal lmg %r0,%r1,0($inp) # just copy 128 bits... @@ -1442,7 +1442,7 @@ $code.=<<___ if (!$softonly && 0);# kmct larl %r1,OPENSSL_s390xcap_P llihh %r0,0x8000 # check if kmctr supports the function code srlg %r0,%r0,0($s0) - ng %r0,64(%r1) # check kmctr capability vector + ng %r0,72(%r1) # check kmctr capability vector lgr %r0,$s0 lgr %r1,$s1 jz .Lctr32_km_loop @@ -1592,7 +1592,7 @@ $code.=<<___ if(1); larl %r1,OPENSSL_s390xcap_P llihh %r0,0x8000 srlg %r0,%r0,32($s1) # check for 32+function code - ng %r0,32(%r1) # check km capability vector + ng %r0,40(%r1) # check km capability vector lgr %r0,$s0 # restore the function code la %r1,0($key1) # restore $key1 jz .Lxts_km_vanilla Index: openssl-1.1.0g/crypto/modes/asm/ghash-s390x.pl =================================================================== --- openssl-1.1.0g.orig/crypto/modes/asm/ghash-s390x.pl 2018-01-10 17:13:05.962202226 +0100 +++ openssl-1.1.0g/crypto/modes/asm/ghash-s390x.pl 2018-01-10 17:13:07.430224756 +0100 @@ -89,7 +89,7 @@ ___ $code.=<<___ if(!$softonly && 0); # hardware is slow for single block... larl %r1,OPENSSL_s390xcap_P lghi %r0,0 - lg %r1,24(%r1) # load second word of kimd capabilities vector + lg %r1,32(%r1) # load second word of kimd capabilities vector tmhh %r1,0x4000 # check for function 65 jz .Lsoft_gmult lghi %r1,-16 @@ -132,7 +132,7 @@ gcm_ghash_4bit: ___ $code.=<<___ if(!$softonly); larl %r1,OPENSSL_s390xcap_P - lg %r0,24(%r1) # load second word of kimd capabilities vector + lg %r0,32(%r1) # load second word of kimd capabilities vector tmhh %r0,0x4000 # check for function 65 jz .Lsoft_ghash lghi %r0,65 # function 65 Index: openssl-1.1.0g/crypto/s390x_arch.h =================================================================== --- openssl-1.1.0g.orig/crypto/s390x_arch.h 2018-01-10 17:13:05.962202226 +0100 +++ openssl-1.1.0g/crypto/s390x_arch.h 2018-01-10 17:13:07.430224756 +0100 @@ -18,11 +18,16 @@ * functions. If STFLE returns fewer doublewords or an instruction is not * supported, the corresponding element is zero. The order is as follows: * - * STFLE:STFLE.KIMD:KIMD:KM:KM:KMC:KMC:KMCTR:KMCTR + * STFLE:STFLE:STFLE.KIMD:KIMD:KM:KM:KMC:KMC:KMCTR:KMCTR */ -# define S390X_STFLE_DWORDS 2 +# define S390X_STFLE_DWORDS 3 # define S390X_QUERY_DWORDS 8 # define S390X_CAP_DWORDS (S390X_STFLE_DWORDS + S390X_QUERY_DWORDS) extern unsigned long long OPENSSL_s390xcap_P[]; +/* OPENSSL_s390xcap_P[2] flags */ +# define S390X_STFLE_VXE (1ULL << 56) +# define S390X_STFLE_VXD (1ULL << 57) +# define S390X_STFLE_VX (1ULL << 62) + #endif Index: openssl-1.1.0g/crypto/s390xcap.c =================================================================== --- openssl-1.1.0g.orig/crypto/s390xcap.c 2018-01-10 17:13:05.962202226 +0100 +++ openssl-1.1.0g/crypto/s390xcap.c 2018-01-10 17:13:07.430224756 +0100 @@ -22,6 +22,31 @@ static void ill_handler(int sig) siglongjmp(ill_jmp, sig); } +/*- + * os-specific function to check if "vector enablement control"-bit and + * "AFP register control"-bit in control register 0 are set. + */ +static int vx_enabled(void) +{ +#if defined(OPENSSL_SYS_LINUX) + FILE *fd; + char buf[4096]; + + if ((fd = fopen("/proc/cpuinfo", "r")) == NULL) + return 0; + + buf[0] = '\0'; + + while ((fgets(buf, sizeof(buf), fd) != NULL) + && (strstr(buf, "features") != buf)); + + fclose(fd); + return (strstr(buf, " vx ") != NULL) ? 1 : 0; +#else + return 0; +#endif +} + void OPENSSL_s390x_facilities(void); void OPENSSL_cpuid_setup(void) @@ -53,6 +78,12 @@ void OPENSSL_cpuid_setup(void) sigaction(SIGILL, &oact, NULL); sigprocmask(SIG_SETMASK, &oset, NULL); + /* protection against disabled vector facility */ + if (!vx_enabled()) { + OPENSSL_s390xcap_P[2] &= ~(S390X_STFLE_VXE | S390X_STFLE_VXD | + S390X_STFLE_VX); + } + if ((env = getenv("OPENSSL_s390xcap")) != NULL) { for (i = 0; i < S390X_CAP_DWORDS; i++) { off = (env[0] == '~') ? 1 : 0; Index: openssl-1.1.0g/crypto/s390xcpuid.S =================================================================== --- openssl-1.1.0g.orig/crypto/s390xcpuid.S 2018-01-10 17:13:05.962202226 +0100 +++ openssl-1.1.0g/crypto/s390xcpuid.S 2018-01-10 17:13:07.430224756 +0100 @@ -21,33 +21,37 @@ OPENSSL_s390x_facilities: stg %r0,56(%r4) stg %r0,64(%r4) stg %r0,72(%r4) + stg %r0,80(%r4) .long 0xb2b04000 # stfle 0(%r4) brc 8,.Ldone lghi %r0,1 .long 0xb2b04000 # stfle 0(%r4) + brc 8,.Ldone + lghi %r0,2 + .long 0xb2b04000 # stfle 0(%r4) .Ldone: lmg %r2,%r3,0(%r4) tmhl %r2,0x4000 # check for message-security-assist jz .Lret lghi %r0,0 # query kimd capabilities - la %r1,16(%r4) + la %r1,24(%r4) .long 0xb93e0002 # kimd %r0,%r2 lghi %r0,0 # query km capability vector - la %r1,32(%r4) + la %r1,40(%r4) .long 0xb92e0042 # km %r4,%r2 lghi %r0,0 # query kmc capability vector - la %r1,48(%r4) + la %r1,56(%r4) .long 0xb92f0042 # kmc %r4,%r2 tmhh %r3,0x0004 # check for message-security-assist-4 jz .Lret lghi %r0,0 # query kmctr capability vector - la %r1,64(%r4) + la %r1,72(%r4) .long 0xb92d2042 # kmctr %r4,%r2,%r2 .Lret: Index: openssl-1.1.0g/crypto/sha/asm/sha1-s390x.pl =================================================================== --- openssl-1.1.0g.orig/crypto/sha/asm/sha1-s390x.pl 2018-01-10 17:13:05.962202226 +0100 +++ openssl-1.1.0g/crypto/sha/asm/sha1-s390x.pl 2018-01-10 17:13:07.430224756 +0100 @@ -172,7 +172,7 @@ sha1_block_data_order: ___ $code.=<<___ if ($kimdfunc); larl %r1,OPENSSL_s390xcap_P - lg %r0,16(%r1) # check kimd capabilities + lg %r0,24(%r1) # check kimd capabilities tmhh %r0,`0x8000>>$kimdfunc` jz .Lsoftware lghi %r0,$kimdfunc Index: openssl-1.1.0g/crypto/sha/asm/sha512-s390x.pl =================================================================== --- openssl-1.1.0g.orig/crypto/sha/asm/sha512-s390x.pl 2018-01-10 17:13:05.962202226 +0100 +++ openssl-1.1.0g/crypto/sha/asm/sha512-s390x.pl 2018-01-10 17:13:07.430224756 +0100 @@ -244,7 +244,7 @@ $Func: ___ $code.=<<___ if ($kimdfunc); larl %r1,OPENSSL_s390xcap_P - lg %r0,16(%r1) # check kimd capabilities + lg %r0,24(%r1) # check kimd capabilities tmhh %r0,`0x8000>>$kimdfunc` jz .Lsoftware lghi %r0,$kimdfunc