[openssl] master update
shane.lontis at oracle.com
shane.lontis at oracle.com
Wed Dec 2 02:08:24 UTC 2020
The branch master has been updated
via 8018352457cf9c98ce59f1e591fcd69f2153b649 (commit)
from f7f10de3059d0f27aa5df95ff346d8639483543c (commit)
- Log -----------------------------------------------------------------
commit 8018352457cf9c98ce59f1e591fcd69f2153b649
Author: Shane Lontis <shane.lontis at oracle.com>
Date: Wed Nov 25 18:19:27 2020 +1000
Fix s390 EDDSA HW support in providers.
Fixes #12476
Note this stopped working when ECX was swapped over to using
providers. The ECX_KEY keygen and exchange were converted, but not the ED
signing support.
Reviewed-by: Matt Caswell <matt at openssl.org>
Reviewed-by: Patrick Steuer <patrick.steuer at de.ibm.com>
(Merged from https://github.com/openssl/openssl/pull/13508)
-----------------------------------------------------------------------
Summary of changes:
providers/implementations/signature/eddsa.c | 143 +++++++++++++++++++++++++++-
1 file changed, 141 insertions(+), 2 deletions(-)
diff --git a/providers/implementations/signature/eddsa.c b/providers/implementations/signature/eddsa.c
index 8f23082a21..57c37096ef 100644
--- a/providers/implementations/signature/eddsa.c
+++ b/providers/implementations/signature/eddsa.c
@@ -23,6 +23,27 @@
#include "prov/der_ecx.h"
#include "crypto/ecx.h"
+#ifdef S390X_EC_ASM
+# include "s390x_arch.h"
+
+# define S390X_CAN_SIGN(edtype) \
+((OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_##edtype)) \
+&& (OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_##edtype)) \
+&& (OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_##edtype)))
+
+static int s390x_ed25519_digestsign(const ECX_KEY *edkey, unsigned char *sig,
+ const unsigned char *tbs, size_t tbslen);
+static int s390x_ed448_digestsign(const ECX_KEY *edkey, unsigned char *sig,
+ const unsigned char *tbs, size_t tbslen);
+static int s390x_ed25519_digestverify(const ECX_KEY *edkey,
+ const unsigned char *sig,
+ const unsigned char *tbs, size_t tbslen);
+static int s390x_ed448_digestverify(const ECX_KEY *edkey,
+ const unsigned char *sig,
+ const unsigned char *tbs, size_t tbslen);
+
+#endif /* S390X_EC_ASM */
+
static OSSL_FUNC_signature_newctx_fn eddsa_newctx;
static OSSL_FUNC_signature_digest_sign_init_fn eddsa_digest_signverify_init;
static OSSL_FUNC_signature_digest_sign_fn ed25519_digest_sign;
@@ -133,7 +154,10 @@ int ed25519_digest_sign(void *vpeddsactx, unsigned char *sigret,
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
return 0;
}
-
+#ifdef S390X_EC_ASM
+ if (S390X_CAN_SIGN(ED25519))
+ return s390x_ed25519_digestsign(edkey, sigret, tbs, tbslen);
+#endif /* S390X_EC_ASM */
if (ED25519_sign(sigret, tbs, tbslen, edkey->pubkey, edkey->privkey,
peddsactx->libctx, NULL) == 0) {
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
@@ -161,7 +185,10 @@ int ed448_digest_sign(void *vpeddsactx, unsigned char *sigret,
ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
return 0;
}
-
+#ifdef S390X_EC_ASM
+ if (S390X_CAN_SIGN(ED448))
+ return s390x_ed448_digestsign(edkey, sigret, tbs, tbslen);
+#endif /* S390X_EC_ASM */
if (ED448_sign(peddsactx->libctx, sigret, tbs, tbslen, edkey->pubkey,
edkey->privkey, NULL, 0, edkey->propq) == 0) {
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN);
@@ -181,6 +208,11 @@ int ed25519_digest_verify(void *vpeddsactx, const unsigned char *sig,
if (!ossl_prov_is_running() || siglen != ED25519_SIGSIZE)
return 0;
+#ifdef S390X_EC_ASM
+ if (S390X_CAN_SIGN(ED25519))
+ return s390x_ed25519_digestverify(edkey, sig, tbs, tbslen);
+#endif /* S390X_EC_ASM */
+
return ED25519_verify(tbs, tbslen, sig, edkey->pubkey, peddsactx->libctx,
edkey->propq);
}
@@ -195,6 +227,11 @@ int ed448_digest_verify(void *vpeddsactx, const unsigned char *sig,
if (!ossl_prov_is_running() || siglen != ED448_SIGSIZE)
return 0;
+#ifdef S390X_EC_ASM
+ if (S390X_CAN_SIGN(ED448))
+ return s390x_ed448_digestverify(edkey, sig, tbs, tbslen);
+#endif /* S390X_EC_ASM */
+
return ED448_verify(peddsactx->libctx, tbs, tbslen, sig, edkey->pubkey,
NULL, 0, edkey->propq);
}
@@ -296,3 +333,105 @@ const OSSL_DISPATCH ossl_ed448_signature_functions[] = {
(void (*)(void))eddsa_gettable_ctx_params },
{ 0, NULL }
};
+
+#ifdef S390X_EC_ASM
+
+static int s390x_ed25519_digestsign(const ECX_KEY *edkey, unsigned char *sig,
+ const unsigned char *tbs, size_t tbslen)
+{
+ int rc;
+ union {
+ struct {
+ unsigned char sig[64];
+ unsigned char priv[32];
+ } ed25519;
+ unsigned long long buff[512];
+ } param;
+
+ memset(¶m, 0, sizeof(param));
+ memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
+
+ rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen);
+ OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
+ if (rc != 0)
+ return 0;
+
+ s390x_flip_endian32(sig, param.ed25519.sig);
+ s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
+ return 1;
+}
+
+static int s390x_ed448_digestsign(const ECX_KEY *edkey, unsigned char *sig,
+ const unsigned char *tbs, size_t tbslen)
+{
+ int rc;
+ union {
+ struct {
+ unsigned char sig[128];
+ unsigned char priv[64];
+ } ed448;
+ unsigned long long buff[512];
+ } param;
+
+ memset(¶m, 0, sizeof(param));
+ memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
+
+ rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen);
+ OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
+ if (rc != 0)
+ return 0;
+
+ s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
+ s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
+ memcpy(sig, param.ed448.sig, 57);
+ memcpy(sig + 57, param.ed448.sig + 64, 57);
+ return 1;
+}
+
+static int s390x_ed25519_digestverify(const ECX_KEY *edkey,
+ const unsigned char *sig,
+ const unsigned char *tbs, size_t tbslen)
+{
+ union {
+ struct {
+ unsigned char sig[64];
+ unsigned char pub[32];
+ } ed25519;
+ unsigned long long buff[512];
+ } param;
+
+ memset(¶m, 0, sizeof(param));
+ s390x_flip_endian32(param.ed25519.sig, sig);
+ s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
+ s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
+
+ return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
+ ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0;
+}
+
+static int s390x_ed448_digestverify(const ECX_KEY *edkey,
+ const unsigned char *sig,
+ const unsigned char *tbs,
+ size_t tbslen)
+{
+ union {
+ struct {
+ unsigned char sig[128];
+ unsigned char pub[64];
+ } ed448;
+ unsigned long long buff[512];
+ } param;
+
+ memset(¶m, 0, sizeof(param));
+ memcpy(param.ed448.sig, sig, 57);
+ s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
+ memcpy(param.ed448.sig + 64, sig + 57, 57);
+ s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
+ memcpy(param.ed448.pub, edkey->pubkey, 57);
+ s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
+
+ return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
+ ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0;
+}
+
+#endif /* S390X_EC_ASM */
More information about the openssl-commits
mailing list