diff options
-rw-r--r-- | crypto/aes/asm/aes-s390x.pl | 11 | ||||
-rw-r--r-- | crypto/aes/build.info | 3 | ||||
-rw-r--r-- | crypto/modes/asm/ghash-s390x.pl | 12 | ||||
-rw-r--r-- | crypto/modes/build.info | 2 | ||||
-rw-r--r-- | crypto/s390x_arch.h | 82 | ||||
-rw-r--r-- | crypto/s390xcap.c | 28 | ||||
-rw-r--r-- | crypto/s390xcpuid.S | 115 | ||||
-rw-r--r-- | crypto/sha/asm/sha1-s390x.pl | 5 | ||||
-rw-r--r-- | crypto/sha/asm/sha512-s390x.pl | 5 | ||||
-rw-r--r-- | crypto/sha/build.info | 7 |
10 files changed, 222 insertions, 48 deletions
diff --git a/crypto/aes/asm/aes-s390x.pl b/crypto/aes/asm/aes-s390x.pl index 77b4640bd6..1495917d26 100644 --- a/crypto/aes/asm/aes-s390x.pl +++ b/crypto/aes/asm/aes-s390x.pl @@ -129,6 +129,8 @@ sub _data_word() } $code=<<___; +#include "s390x_arch.h" + .text .type AES_Te,\@object @@ -823,8 +825,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,S390X_KM(%r1) # check availability of both km... + ng %r0,S390X_KMC(%r1) # ...and kmc support for given key length jz .Lekey_internal lmg %r0,%r1,0($inp) # just copy 128 bits... @@ -1442,7 +1444,7 @@ $code.=<<___ if (!$softonly && 0);# kmctr code was measured to be ~12% slower 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,S390X_KMCTR(%r1) # check kmctr capability vector lgr %r0,$s0 lgr %r1,$s1 jz .Lctr32_km_loop @@ -1592,7 +1594,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,S390X_KM(%r1) # check km capability vector lgr %r0,$s0 # restore the function code la %r1,0($key1) # restore $key1 jz .Lxts_km_vanilla @@ -2219,7 +2221,6 @@ ___ } $code.=<<___; .string "AES for s390x, CRYPTOGAMS by <appro\@openssl.org>" -.comm OPENSSL_s390xcap_P,80,8 ___ $code =~ s/\`([^\`]*)\`/eval $1/gem; diff --git a/crypto/aes/build.info b/crypto/aes/build.info index bcc71abaeb..84c62208f6 100644 --- a/crypto/aes/build.info +++ b/crypto/aes/build.info @@ -46,6 +46,9 @@ INCLUDE[aes-armv4.o]=.. GENERATE[bsaes-armv7.S]=asm/bsaes-armv7.pl $(PERLASM_SCHEME) INCLUDE[bsaes-armv7.o]=.. +GENERATE[aes-s390x.S]=asm/aes-s390x.pl $(PERLASM_SCHEME) +INCLUDE[aes-s390x.o]=.. + BEGINRAW[Makefile] ##### AES assembler implementations diff --git a/crypto/modes/asm/ghash-s390x.pl b/crypto/modes/asm/ghash-s390x.pl index 469aefa7b3..17dc375053 100644 --- a/crypto/modes/asm/ghash-s390x.pl +++ b/crypto/modes/asm/ghash-s390x.pl @@ -80,6 +80,8 @@ $rem_4bit="%r14"; $sp="%r15"; $code.=<<___; +#include "s390x_arch.h" + .text .globl gcm_gmult_4bit @@ -89,12 +91,13 @@ ___ $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,S390X_KIMD+8(%r1) # load second word of kimd capabilities + # vector tmhh %r1,0x4000 # check for function 65 jz .Lsoft_gmult stg %r0,16($sp) # arrange 16 bytes of zero input stg %r0,24($sp) - lghi %r0,65 # function 65 + lghi %r0,S390X_GHASH # function 65 la %r1,0($Xi) # H lies right after Xi in gcm128_context la $inp,16($sp) lghi $len,16 @@ -123,10 +126,11 @@ gcm_ghash_4bit: ___ $code.=<<___ if(!$softonly); larl %r1,OPENSSL_s390xcap_P - lg %r0,24(%r1) # load second word of kimd capabilities vector + lg %r0,S390X_KIMD+8(%r1) # load second word of kimd capabilities + # vector tmhh %r0,0x4000 # check for function 65 jz .Lsoft_ghash - lghi %r0,65 # function 65 + lghi %r0,S390X_GHASH # function 65 la %r1,0($Xi) # H lies right after Xi in gcm128_context .long 0xb93e0004 # kimd %r0,$inp brc 1,.-4 # pay attention to "partial completion" diff --git a/crypto/modes/build.info b/crypto/modes/build.info index 38195c44a5..b794c5041a 100644 --- a/crypto/modes/build.info +++ b/crypto/modes/build.info @@ -19,6 +19,8 @@ GENERATE[ghash-armv4.S]=asm/ghash-armv4.pl $(PERLASM_SCHEME) INCLUDE[ghash-armv4.o]=.. GENERATE[ghashv8-armx.S]=asm/ghashv8-armx.pl $(PERLASM_SCHEME) INCLUDE[ghashv8-armx.o]=.. +GENERATE[ghash-s390x.S]=asm/ghash-s390x.pl $(PERLASM_SCHEME) +INCLUDE[ghash-s390x.o]=.. BEGINRAW[Makefile] # GNU make "catch all" diff --git a/crypto/s390x_arch.h b/crypto/s390x_arch.h new file mode 100644 index 0000000000..25859851e5 --- /dev/null +++ b/crypto/s390x_arch.h @@ -0,0 +1,82 @@ +/* + * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef S390X_ARCH_H +# define S390X_ARCH_H + +# ifndef __ASSEMBLER__ + +/* + * The field elements of OPENSSL_s390xcap_P are the 64-bit words returned by + * the STFLE instruction followed by the 64-bit word pairs returned by + * instructions' QUERY functions. If STFLE returns fewer data or an instruction + * is not supported, the corresponding field elements are zero. + */ +struct OPENSSL_s390xcap_st { + unsigned long long stfle[4]; + unsigned long long kimd[2]; + unsigned long long klmd[2]; + unsigned long long km[2]; + unsigned long long kmc[2]; + unsigned long long kmac[2]; + unsigned long long kmctr[2]; + unsigned long long kmo[2]; + unsigned long long kmf[2]; + unsigned long long prno[2]; + unsigned long long kma[2]; +}; + +extern struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P; + +/* convert facility bit number or function code to bit mask */ +# define S390X_CAPBIT(i) (1ULL << (63 - (i) % 64)) + +# endif + +/* OPENSSL_s390xcap_P offsets [bytes] */ +# define S390X_STFLE 0x00 +# define S390X_KIMD 0x20 +# define S390X_KLMD 0x30 +# define S390X_KM 0x40 +# define S390X_KMC 0x50 +# define S390X_KMAC 0x60 +# define S390X_KMCTR 0x70 +# define S390X_KMO 0x80 +# define S390X_KMF 0x90 +# define S390X_PRNO 0xa0 +# define S390X_KMA 0xb0 + +/* Facility Bit Numbers */ +# define S390X_VX 129 +# define S390X_VXD 134 +# define S390X_VXE 135 + +/* Function Codes */ + +/* all instructions */ +# define S390X_QUERY 0 + +/* kimd/klmd */ +# define S390X_SHA3_224 32 +# define S390X_SHA3_256 33 +# define S390X_SHA3_384 34 +# define S390X_SHA3_512 35 +# define S390X_SHAKE_128 36 +# define S390X_SHAKE_256 37 +# define S390X_GHASH 65 + +/* km/kmc/kmac/kmctr/kmo/kmf/kma */ +# define S390X_AES_128 18 +# define S390X_AES_192 19 +# define S390X_AES_256 20 + +/* prno */ +# define S390X_TRNG 114 + +#endif diff --git a/crypto/s390xcap.c b/crypto/s390xcap.c index 93c5327ffb..e7c7f0a357 100644 --- a/crypto/s390xcap.c +++ b/crypto/s390xcap.c @@ -1,5 +1,5 @@ /* - * Copyright 2010-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2010-2017 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the OpenSSL license (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -13,8 +13,7 @@ #include <setjmp.h> #include <signal.h> #include "internal/cryptlib.h" - -extern unsigned long OPENSSL_s390xcap_P[]; +#include "s390x_arch.h" static sigjmp_buf ill_jmp; static void ill_handler(int sig) @@ -22,30 +21,47 @@ static void ill_handler(int sig) siglongjmp(ill_jmp, sig); } -unsigned long OPENSSL_s390x_facilities(void); +void OPENSSL_s390x_facilities(void); +void OPENSSL_vx_probe(void); + +struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P; void OPENSSL_cpuid_setup(void) { sigset_t oset; struct sigaction ill_act, oact; - if (OPENSSL_s390xcap_P[0]) + if (OPENSSL_s390xcap_P.stfle[0]) return; - OPENSSL_s390xcap_P[0] = 1UL << (8 * sizeof(unsigned long) - 1); + /* set a bit that will not be tested later */ + OPENSSL_s390xcap_P.stfle[0] |= S390X_CAPBIT(0); memset(&ill_act, 0, sizeof(ill_act)); ill_act.sa_handler = ill_handler; sigfillset(&ill_act.sa_mask); sigdelset(&ill_act.sa_mask, SIGILL); + sigdelset(&ill_act.sa_mask, SIGFPE); sigdelset(&ill_act.sa_mask, SIGTRAP); sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset); sigaction(SIGILL, &ill_act, &oact); + sigaction(SIGFPE, &ill_act, &oact); /* protection against missing store-facility-list-extended */ if (sigsetjmp(ill_jmp, 1) == 0) OPENSSL_s390x_facilities(); + /* protection against disabled vector facility */ + if ((OPENSSL_s390xcap_P.stfle[2] & S390X_CAPBIT(S390X_VX)) + && (sigsetjmp(ill_jmp, 1) == 0)) { + OPENSSL_vx_probe(); + } else { + OPENSSL_s390xcap_P.stfle[2] &= ~(S390X_CAPBIT(S390X_VX) + | S390X_CAPBIT(S390X_VXD) + | S390X_CAPBIT(S390X_VXE)); + } + + sigaction(SIGFPE, &oact, NULL); sigaction(SIGILL, &oact, NULL); sigprocmask(SIG_SETMASK, &oset, NULL); } diff --git a/crypto/s390xcpuid.S b/crypto/s390xcpuid.S index 8859e9e64a..9aa23c3e46 100644 --- a/crypto/s390xcpuid.S +++ b/crypto/s390xcpuid.S @@ -6,49 +6,100 @@ // in the file LICENSE in the source distribution or at // https://www.openssl.org/source/license.html +#include "s390x_arch.h" + .globl OPENSSL_s390x_facilities .type OPENSSL_s390x_facilities,@function .align 16 OPENSSL_s390x_facilities: lghi %r0,0 larl %r4,OPENSSL_s390xcap_P - stg %r0,8(%r4) # wipe capability vectors - stg %r0,16(%r4) - stg %r0,24(%r4) - stg %r0,32(%r4) - stg %r0,40(%r4) - stg %r0,48(%r4) - stg %r0,56(%r4) - stg %r0,64(%r4) - stg %r0,72(%r4) - - .long 0xb2b04000 # stfle 0(%r4) + + stg %r0,S390X_STFLE+8(%r4) # wipe capability vectors + stg %r0,S390X_STFLE+16(%r4) + stg %r0,S390X_STFLE+24(%r4) + stg %r0,S390X_KIMD(%r4) + stg %r0,S390X_KIMD+8(%r4) + stg %r0,S390X_KLMD(%r4) + stg %r0,S390X_KLMD+8(%r4) + stg %r0,S390X_KM(%r4) + stg %r0,S390X_KM+8(%r4) + stg %r0,S390X_KMC(%r4) + stg %r0,S390X_KMC+8(%r4) + stg %r0,S390X_KMAC(%r4) + stg %r0,S390X_KMAC+8(%r4) + stg %r0,S390X_KMCTR(%r4) + stg %r0,S390X_KMCTR+8(%r4) + stg %r0,S390X_KMO(%r4) + stg %r0,S390X_KMO+8(%r4) + stg %r0,S390X_KMF(%r4) + stg %r0,S390X_KMF+8(%r4) + stg %r0,S390X_PRNO(%r4) + stg %r0,S390X_PRNO+8(%r4) + stg %r0,S390X_KMA(%r4) + stg %r0,S390X_KMA+8(%r4) + + .long 0xb2b04000 # stfle 0(%r4) brc 8,.Ldone lghi %r0,1 - .long 0xb2b04000 # stfle 0(%r4) + .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 + lmg %r2,%r3,S390X_STFLE(%r4) + tmhl %r2,0x4000 # check for message-security-assist jz .Lret - lghi %r0,0 # query kimd capabilities - la %r1,16(%r4) - .long 0xb93e0002 # kimd %r0,%r2 + lghi %r0,S390X_QUERY # query kimd capabilities + la %r1,S390X_KIMD(%r4) + .long 0xb93e0002 # kimd %r0,%r2 + + lghi %r0,S390X_QUERY # query klmd capabilities + la %r1,S390X_KLMD(%r4) + .long 0xb93f0002 # klmd %r0,%r2 + + lghi %r0,S390X_QUERY # query km capability vector + la %r1,S390X_KM(%r4) + .long 0xb92e0042 # km %r4,%r2 - lghi %r0,0 # query km capability vector - la %r1,32(%r4) - .long 0xb92e0042 # km %r4,%r2 + lghi %r0,S390X_QUERY # query kmc capability vector + la %r1,S390X_KMC(%r4) + .long 0xb92f0042 # kmc %r4,%r2 - lghi %r0,0 # query kmc capability vector - la %r1,48(%r4) - .long 0xb92f0042 # kmc %r4,%r2 + lghi %r0,S390X_QUERY # query kmac capability vector + la %r1,S390X_KMAC(%r4) + .long 0xb91e0042 # kmac %r4,%r2 - tmhh %r3,0x0004 # check for message-security-assist-4 + tmhh %r3,0x0004 # check for message-security-assist-4 jz .Lret - lghi %r0,0 # query kmctr capability vector - la %r1,64(%r4) - .long 0xb92d2042 # kmctr %r4,%r2,%r2 + lghi %r0,S390X_QUERY # query kmctr capability vector + la %r1,S390X_KMCTR(%r4) + .long 0xb92d2042 # kmctr %r4,%r2,%r2 + + lghi %r0,S390X_QUERY # query kmo capability vector + la %r1,S390X_KMO(%r4) + .long 0xb92b0042 # kmo %r4,%r2 + + lghi %r0,S390X_QUERY # query kmf capability vector + la %r1,S390X_KMF(%r4) + .long 0xb92a0042 # kmf %r4,%r2 + + tml %r2,0x40 # check for message-security-assist-5 + jz .Lret + + lghi %r0,S390X_QUERY # query prno capability vector + la %r1,S390X_PRNO(%r4) + .long 0xb93c0042 # prno %r4,%r2 + + lg %r2,S390X_STFLE+16(%r4) + tmhl %r2,0x2000 # check for message-security-assist-8 + jz .Lret + + lghi %r0,S390X_QUERY # query kma capability vector + la %r1,S390X_KMA(%r4) + .long 0xb9294022 # kma %r2,%r4,%r2 .Lret: br %r14 @@ -174,7 +225,13 @@ OPENSSL_instrument_bus2: br %r14 .size OPENSSL_instrument_bus2,.-OPENSSL_instrument_bus2 +.globl OPENSSL_vx_probe +.type OPENSSL_vx_probe,@function +.align 16 +OPENSSL_vx_probe: + .word 0xe700,0x0000,0x0044 # vzero %v0 + br %r14 +.size OPENSSL_vx_probe,.-OPENSSL_vx_probe + .section .init brasl %r14,OPENSSL_cpuid_setup - -.comm OPENSSL_s390xcap_P,80,8 diff --git a/crypto/sha/asm/sha1-s390x.pl b/crypto/sha/asm/sha1-s390x.pl index 1ea1279e09..5729c30898 100644 --- a/crypto/sha/asm/sha1-s390x.pl +++ b/crypto/sha/asm/sha1-s390x.pl @@ -160,6 +160,8 @@ ___ } $code.=<<___; +#include "s390x_arch.h" + .text .align 64 .type Ktable,\@object @@ -172,7 +174,7 @@ sha1_block_data_order: ___ $code.=<<___ if ($kimdfunc); larl %r1,OPENSSL_s390xcap_P - lg %r0,16(%r1) # check kimd capabilities + lg %r0,S390X_KIMD(%r1) # check kimd capabilities tmhh %r0,`0x8000>>$kimdfunc` jz .Lsoftware lghi %r0,$kimdfunc @@ -239,7 +241,6 @@ $code.=<<___; br %r14 .size sha1_block_data_order,.-sha1_block_data_order .string "SHA1 block transform for s390x, CRYPTOGAMS by <appro\@openssl.org>" -.comm OPENSSL_s390xcap_P,80,8 ___ $code =~ s/\`([^\`]*)\`/eval $1/gem; diff --git a/crypto/sha/asm/sha512-s390x.pl b/crypto/sha/asm/sha512-s390x.pl index 8ae91c2e96..4c0f4e7931 100644 --- a/crypto/sha/asm/sha512-s390x.pl +++ b/crypto/sha/asm/sha512-s390x.pl @@ -170,6 +170,8 @@ ___ } $code.=<<___; +#include "s390x_arch.h" + .text .align 64 .type $Table,\@object @@ -244,7 +246,7 @@ $Func: ___ $code.=<<___ if ($kimdfunc); larl %r1,OPENSSL_s390xcap_P - lg %r0,16(%r1) # check kimd capabilities + lg %r0,S390X_KIMD(%r1) # check kimd capabilities tmhh %r0,`0x8000>>$kimdfunc` jz .Lsoftware lghi %r0,$kimdfunc @@ -312,7 +314,6 @@ $code.=<<___; br %r14 .size $Func,.-$Func .string "SHA${label} block transform for s390x, CRYPTOGAMS by <appro\@openssl.org>" -.comm OPENSSL_s390xcap_P,80,8 ___ $code =~ s/\`([^\`]*)\`/eval $1/gem; diff --git a/crypto/sha/build.info b/crypto/sha/build.info index 7686f9fd62..728c156ffc 100644 --- a/crypto/sha/build.info +++ b/crypto/sha/build.info @@ -60,6 +60,13 @@ INCLUDE[sha256-armv8.o]=.. GENERATE[sha512-armv8.S]=asm/sha512-armv8.pl $(PERLASM_SCHEME) INCLUDE[sha512-armv8.o]=.. +GENERATE[sha1-s390x.S]=asm/sha1-s390x.pl $(PERLASM_SCHEME) +INCLUDE[sha1-s390x.o]=.. +GENERATE[sha256-s390x.S]=asm/sha512-s390x.pl $(PERLASM_SCHEME) +INCLUDE[sha256-s390x.o]=.. +GENERATE[sha512-s390x.S]=asm/sha512-s390x.pl $(PERLASM_SCHEME) +INCLUDE[sha512-s390x.o]=.. + BEGINRAW[Makefile(unix)] ##### SHA assembler implementations |