From 97b50f67f212589661c9f1edd5285822c6cc642b Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Tue, 4 Feb 2020 16:41:19 +0000 Subject: [PATCH] Add S390 support for provider based X25519/X448 Reviewed-by: Patrick Steuer Reviewed-by: Shane Lontis (Merged from https://github.com/openssl/openssl/pull/10964) --- crypto/ec/ecx_meth.c | 12 +++++----- include/crypto/ecx.h | 7 ++++++ providers/implementations/exchange/build.info | 12 ++++++++++ providers/implementations/exchange/ecx_exch.c | 23 +++++++++++++++++++ 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/crypto/ec/ecx_meth.c b/crypto/ec/ecx_meth.c index 88787e0db6..32817562bf 100644 --- a/crypto/ec/ecx_meth.c +++ b/crypto/ec/ecx_meth.c @@ -951,9 +951,9 @@ static void s390x_x448_mod_p(unsigned char u[56]) u, u_red, sizeof(u_red)); } -static int s390x_x25519_mul(unsigned char u_dst[32], - const unsigned char u_src[32], - const unsigned char d_src[32]) +int s390x_x25519_mul(unsigned char u_dst[32], + const unsigned char u_src[32], + const unsigned char d_src[32]) { union { struct { @@ -984,9 +984,9 @@ static int s390x_x25519_mul(unsigned char u_dst[32], return rc; } -static int s390x_x448_mul(unsigned char u_dst[56], - const unsigned char u_src[56], - const unsigned char d_src[56]) +int s390x_x448_mul(unsigned char u_dst[56], + const unsigned char u_src[56], + const unsigned char d_src[56]) { union { struct { diff --git a/include/crypto/ecx.h b/include/crypto/ecx.h index 3f0bbe1bb9..e179db1b53 100644 --- a/include/crypto/ecx.h +++ b/include/crypto/ecx.h @@ -63,5 +63,12 @@ int X448(uint8_t out_shared_key[56], const uint8_t private_key[56], void X448_public_from_private(uint8_t out_public_value[56], const uint8_t private_key[56]); +int s390x_x25519_mul(unsigned char u_dst[32], + const unsigned char u_src[32], + const unsigned char d_src[32]); +int s390x_x448_mul(unsigned char u_dst[56], + const unsigned char u_src[56], + const unsigned char d_src[56]); + # endif /* OPENSSL_NO_EC */ #endif diff --git a/providers/implementations/exchange/build.info b/providers/implementations/exchange/build.info index 0c2b98631b..c74e122844 100644 --- a/providers/implementations/exchange/build.info +++ b/providers/implementations/exchange/build.info @@ -8,4 +8,16 @@ IF[{- !$disabled{dh} -}] SOURCE[$DH_GOAL]=dh_exch.c ENDIF +IF[{- !$disabled{asm} -}] + $ECDEF_s390x=S390X_EC_ASM + + # Now that we have defined all the arch specific variables, use the + # appropriate one, and define the appropriate macros + IF[$ECASM_{- $target{asm_arch} -}] + $ECDEF=$ECDEF_{- $target{asm_arch} -} + ENDIF +ENDIF + + SOURCE[$ECX_GOAL]=ecx_exch.c +DEFINE[$ECX_GOAL]=$ECDEF diff --git a/providers/implementations/exchange/ecx_exch.c b/providers/implementations/exchange/ecx_exch.c index b7d1d9e395..ea12628937 100644 --- a/providers/implementations/exchange/ecx_exch.c +++ b/providers/implementations/exchange/ecx_exch.c @@ -16,6 +16,9 @@ #include "crypto/ecx.h" #include "prov/implementations.h" #include "prov/providercommonerr.h" +#ifdef S390X_EC_ASM +# include "s390x_arch.h" +#endif static OSSL_OP_keyexch_newctx_fn x25519_newctx; static OSSL_OP_keyexch_newctx_fn x448_newctx; @@ -126,11 +129,31 @@ static int ecx_derive(void *vecxctx, unsigned char *secret, size_t *secretlen, } if (ecxctx->keylen == X25519_KEYLEN) { +#ifdef S390X_EC_ASM + if (OPENSSL_s390xcap_P.pcc[1] + & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519)) { + if (s390x_x25519_mul(secret, ecxctx->peerkey->pubkey, + ecxctx->key->privkey) == 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_DURING_DERIVATION); + return 0; + } + } else +#endif if (X25519(secret, ecxctx->key->privkey, ecxctx->peerkey->pubkey) == 0) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_DURING_DERIVATION); return 0; } } else { +#ifdef S390X_EC_ASM + if (OPENSSL_s390xcap_P.pcc[1] + & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448)) { + if (s390x_x448_mul(secret, ecxctx->peerkey->pubkey, + ecxctx->key->privkey) == 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_DURING_DERIVATION); + return 0; + } + } else +#endif if (X448(secret, ecxctx->key->privkey, ecxctx->peerkey->pubkey) == 0) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_DURING_DERIVATION); return 0; -- 2.25.1