openssl-1_1/openssl-s390x-assembly-pack-accelerate-ECDSA.patch

279 lines
12 KiB
Diff
Raw Normal View History

2020-01-24 12:52:58 +01:00
From 58c35587eacba090414522a6506cb86f2d0e91af Mon Sep 17 00:00:00 2001
From: Patrick Steuer <patrick.steuer@de.ibm.com>
Date: Thu, 11 Jul 2019 10:38:18 +0200
Subject: [PATCH 09206/10000] s390x assembly pack: accelerate ECDSA
for NIST P-256, P-384 and P-521 using KDSA instruction.
Signed-off-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/9348)
---
crypto/ec/ecp_s390x_nistp.c | 202 +++++++++++++++++++++++++++++++++++-
crypto/err/openssl.txt | 2 +
2 files changed, 200 insertions(+), 4 deletions(-)
Accepting request 786956 from home:vitezslav_cizek:branches:security:tls - Update to 1.1.1e * Properly detect EOF while reading in libssl. Previously if we hit an EOF while reading in libssl then we would report an error back to the application (SSL_ERROR_SYSCALL) but errno would be 0. We now add an error to the stack (which means we instead return SSL_ERROR_SSL) and therefore give a hint as to what went wrong. * Check that ed25519 and ed448 are allowed by the security level. Previously signature algorithms not using an MD were not being checked that they were allowed by the security level. * Fixed SSL_get_servername() behaviour. The behaviour of SSL_get_servername() was not quite right. The behaviour was not consistent between resumption and normal handshakes, and also not quite consistent with historical behaviour. The behaviour in various scenarios has been clarified and it has been updated to make it match historical behaviour as closely as possible. * Corrected the documentation of the return values from the EVP_DigestSign* set of functions. The documentation mentioned negative values for some errors, but this was never the case, so the mention of negative values was removed. * Added a new method to gather entropy on VMS, based on SYS$GET_ENTROPY. The presence of this system service is determined at run-time. * Added newline escaping functionality to a filename when using openssl dgst. This output format is to replicate the output format found in the '*sum' checksum programs. This aims to preserve backward compatibility. * Print all values for a PKCS#12 attribute with 'openssl pkcs12', not just the first value. - Update bunch of patches as the internal crypto headers got reorganized - drop openssl-1_1-CVE-2019-1551.patch (upstream) - openssl dgst: default to SHA256 only when called without a digest, OBS-URL: https://build.opensuse.org/request/show/786956 OBS-URL: https://build.opensuse.org/package/show/security:tls/openssl-1_1?expand=0&rev=65
2020-03-20 18:43:35 +01:00
Index: openssl-1.1.1e/crypto/ec/ecp_s390x_nistp.c
===================================================================
--- openssl-1.1.1e.orig/crypto/ec/ecp_s390x_nistp.c 2020-03-20 13:13:44.618571104 +0100
+++ openssl-1.1.1e/crypto/ec/ecp_s390x_nistp.c 2020-03-20 13:14:20.398759363 +0100
2020-01-24 12:52:58 +01:00
@@ -10,6 +10,7 @@
#include <stdlib.h>
#include <string.h>
#include <openssl/err.h>
+#include <openssl/rand.h>
Accepting request 786956 from home:vitezslav_cizek:branches:security:tls - Update to 1.1.1e * Properly detect EOF while reading in libssl. Previously if we hit an EOF while reading in libssl then we would report an error back to the application (SSL_ERROR_SYSCALL) but errno would be 0. We now add an error to the stack (which means we instead return SSL_ERROR_SSL) and therefore give a hint as to what went wrong. * Check that ed25519 and ed448 are allowed by the security level. Previously signature algorithms not using an MD were not being checked that they were allowed by the security level. * Fixed SSL_get_servername() behaviour. The behaviour of SSL_get_servername() was not quite right. The behaviour was not consistent between resumption and normal handshakes, and also not quite consistent with historical behaviour. The behaviour in various scenarios has been clarified and it has been updated to make it match historical behaviour as closely as possible. * Corrected the documentation of the return values from the EVP_DigestSign* set of functions. The documentation mentioned negative values for some errors, but this was never the case, so the mention of negative values was removed. * Added a new method to gather entropy on VMS, based on SYS$GET_ENTROPY. The presence of this system service is determined at run-time. * Added newline escaping functionality to a filename when using openssl dgst. This output format is to replicate the output format found in the '*sum' checksum programs. This aims to preserve backward compatibility. * Print all values for a PKCS#12 attribute with 'openssl pkcs12', not just the first value. - Update bunch of patches as the internal crypto headers got reorganized - drop openssl-1_1-CVE-2019-1551.patch (upstream) - openssl dgst: default to SHA256 only when called without a digest, OBS-URL: https://build.opensuse.org/request/show/786956 OBS-URL: https://build.opensuse.org/package/show/security:tls/openssl-1_1?expand=0&rev=65
2020-03-20 18:43:35 +01:00
#include "ec_local.h"
2020-01-24 12:52:58 +01:00
#include "s390x_arch.h"
@@ -28,6 +29,15 @@
#define S390X_OFF_SRC_Y(n) (3 * n)
#define S390X_OFF_SCALAR(n) (4 * n)
+/* Offsets of fields in KDSA parameter blocks */
+#define S390X_OFF_R(n) (0 * n)
+#define S390X_OFF_S(n) (1 * n)
+#define S390X_OFF_H(n) (2 * n)
+#define S390X_OFF_K(n) (3 * n)
+#define S390X_OFF_X(n) (3 * n)
+#define S390X_OFF_RN(n) (4 * n)
+#define S390X_OFF_Y(n) (4 * n)
+
static int ec_GFp_s390x_nistp_mul(const EC_GROUP *group, EC_POINT *r,
const BIGNUM *scalar,
size_t num, const EC_POINT *points[],
@@ -106,6 +116,163 @@ ret:
return rc;
}
+static ECDSA_SIG *ecdsa_s390x_nistp_sign_sig(const unsigned char *dgst,
+ int dgstlen,
+ const BIGNUM *kinv,
+ const BIGNUM *r,
+ EC_KEY *eckey,
+ unsigned int fc, int len)
+{
+ unsigned char param[S390X_SIZE_PARAM];
+ int ok = 0;
+ BIGNUM *k;
+ ECDSA_SIG *sig;
+ const EC_GROUP *group;
+ const BIGNUM *privkey;
+ int off;
+
+ group = EC_KEY_get0_group(eckey);
+ privkey = EC_KEY_get0_private_key(eckey);
+ if (group == NULL || privkey == NULL) {
+ ECerr(EC_F_ECDSA_S390X_NISTP_SIGN_SIG, EC_R_MISSING_PARAMETERS);
+ return NULL;
+ }
+
+ if (!EC_KEY_can_sign(eckey)) {
+ ECerr(EC_F_ECDSA_S390X_NISTP_SIGN_SIG,
+ EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
+ return NULL;
+ }
+
+ k = BN_secure_new();
+ sig = ECDSA_SIG_new();
+ if (k == NULL || sig == NULL) {
+ ECerr(EC_F_ECDSA_S390X_NISTP_SIGN_SIG, ERR_R_MALLOC_FAILURE);
+ goto ret;
+ }
+
+ sig->r = BN_new();
+ sig->s = BN_new();
+ if (sig->r == NULL || sig->s == NULL) {
+ ECerr(EC_F_ECDSA_S390X_NISTP_SIGN_SIG, ERR_R_MALLOC_FAILURE);
+ goto ret;
+ }
+
+ memset(param, 0, sizeof(param));
+ off = len - (dgstlen > len ? len : dgstlen);
+ memcpy(param + S390X_OFF_H(len) + off, dgst, len - off);
+
+ if (BN_bn2binpad(privkey, param + S390X_OFF_K(len), len) == -1) {
+ ECerr(EC_F_ECDSA_S390X_NISTP_SIGN_SIG, ERR_R_BN_LIB);
+ goto ret;
+ }
+
+ if (r == NULL || kinv == NULL) {
+ /*
+ * Generate random k and copy to param param block. RAND_priv_bytes
+ * is used instead of BN_priv_rand_range or BN_generate_dsa_nonce
+ * because kdsa instruction constructs an in-range, invertible nonce
+ * internally implementing counter-measures for RNG weakness.
+ */
+ if (RAND_priv_bytes(param + S390X_OFF_RN(len), len) != 1) {
+ ECerr(EC_F_ECDSA_S390X_NISTP_SIGN_SIG,
+ EC_R_RANDOM_NUMBER_GENERATION_FAILED);
+ goto ret;
+ }
+ } else {
+ /* Reconstruct k = (k^-1)^-1. */
+ if (ec_group_do_inverse_ord(group, k, kinv, NULL) == 0
+ || BN_bn2binpad(k, param + S390X_OFF_RN(len), len) == -1) {
+ ECerr(EC_F_ECDSA_S390X_NISTP_SIGN_SIG, ERR_R_BN_LIB);
+ goto ret;
+ }
+ /* Turns KDSA internal nonce-generation off. */
+ fc |= S390X_KDSA_D;
+ }
+
+ if (s390x_kdsa(fc, param, NULL, 0) != 0) {
+ ECerr(EC_F_ECDSA_S390X_NISTP_SIGN_SIG, ERR_R_ECDSA_LIB);
+ goto ret;
+ }
+
+ if (BN_bin2bn(param + S390X_OFF_R(len), len, sig->r) == NULL
+ || BN_bin2bn(param + S390X_OFF_S(len), len, sig->s) == NULL) {
+ ECerr(EC_F_ECDSA_S390X_NISTP_SIGN_SIG, ERR_R_BN_LIB);
+ goto ret;
+ }
+
+ ok = 1;
+ret:
+ OPENSSL_cleanse(param, sizeof(param));
+ if (ok != 1) {
+ ECDSA_SIG_free(sig);
+ sig = NULL;
+ }
+ BN_clear_free(k);
+ return sig;
+}
+
+static int ecdsa_s390x_nistp_verify_sig(const unsigned char *dgst, int dgstlen,
+ const ECDSA_SIG *sig, EC_KEY *eckey,
+ unsigned int fc, int len)
+{
+ unsigned char param[S390X_SIZE_PARAM];
+ int rc = -1;
+ BN_CTX *ctx;
+ BIGNUM *x, *y;
+ const EC_GROUP *group;
+ const EC_POINT *pubkey;
+ int off;
+
+ group = EC_KEY_get0_group(eckey);
+ pubkey = EC_KEY_get0_public_key(eckey);
+ if (eckey == NULL || group == NULL || pubkey == NULL || sig == NULL) {
+ ECerr(EC_F_ECDSA_S390X_NISTP_VERIFY_SIG, EC_R_MISSING_PARAMETERS);
+ return -1;
+ }
+
+ if (!EC_KEY_can_sign(eckey)) {
+ ECerr(EC_F_ECDSA_S390X_NISTP_VERIFY_SIG,
+ EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING);
+ return -1;
+ }
+
+ ctx = BN_CTX_new();
+ if (ctx == NULL) {
+ ECerr(EC_F_ECDSA_S390X_NISTP_VERIFY_SIG, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+
+ BN_CTX_start(ctx);
+
+ x = BN_CTX_get(ctx);
+ y = BN_CTX_get(ctx);
+ if (x == NULL || y == NULL) {
+ ECerr(EC_F_ECDSA_S390X_NISTP_VERIFY_SIG, ERR_R_MALLOC_FAILURE);
+ goto ret;
+ }
+
+ memset(param, 0, sizeof(param));
+ off = len - (dgstlen > len ? len : dgstlen);
+ memcpy(param + S390X_OFF_H(len) + off, dgst, len - off);
+
+ if (group->meth->point_get_affine_coordinates(group, pubkey,
+ x, y, ctx) != 1
+ || BN_bn2binpad(sig->r, param + S390X_OFF_R(len), len) == -1
+ || BN_bn2binpad(sig->s, param + S390X_OFF_S(len), len) == -1
+ || BN_bn2binpad(x, param + S390X_OFF_X(len), len) == -1
+ || BN_bn2binpad(y, param + S390X_OFF_Y(len), len) == -1) {
+ ECerr(EC_F_ECDSA_S390X_NISTP_VERIFY_SIG, ERR_R_BN_LIB);
+ goto ret;
+ }
+
+ rc = s390x_kdsa(fc, param, NULL, 0) == 0 ? 1 : 0;
+ret:
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ return rc;
+}
+
#define EC_GFP_S390X_NISTP_METHOD(bits) \
\
static int ec_GFp_s390x_nistp##bits##_mul(const EC_GROUP *group, \
Accepting request 786956 from home:vitezslav_cizek:branches:security:tls - Update to 1.1.1e * Properly detect EOF while reading in libssl. Previously if we hit an EOF while reading in libssl then we would report an error back to the application (SSL_ERROR_SYSCALL) but errno would be 0. We now add an error to the stack (which means we instead return SSL_ERROR_SSL) and therefore give a hint as to what went wrong. * Check that ed25519 and ed448 are allowed by the security level. Previously signature algorithms not using an MD were not being checked that they were allowed by the security level. * Fixed SSL_get_servername() behaviour. The behaviour of SSL_get_servername() was not quite right. The behaviour was not consistent between resumption and normal handshakes, and also not quite consistent with historical behaviour. The behaviour in various scenarios has been clarified and it has been updated to make it match historical behaviour as closely as possible. * Corrected the documentation of the return values from the EVP_DigestSign* set of functions. The documentation mentioned negative values for some errors, but this was never the case, so the mention of negative values was removed. * Added a new method to gather entropy on VMS, based on SYS$GET_ENTROPY. The presence of this system service is determined at run-time. * Added newline escaping functionality to a filename when using openssl dgst. This output format is to replicate the output format found in the '*sum' checksum programs. This aims to preserve backward compatibility. * Print all values for a PKCS#12 attribute with 'openssl pkcs12', not just the first value. - Update bunch of patches as the internal crypto headers got reorganized - drop openssl-1_1-CVE-2019-1551.patch (upstream) - openssl dgst: default to SHA256 only when called without a digest, OBS-URL: https://build.opensuse.org/request/show/786956 OBS-URL: https://build.opensuse.org/package/show/security:tls/openssl-1_1?expand=0&rev=65
2020-03-20 18:43:35 +01:00
@@ -122,6 +289,29 @@ static int ec_GFp_s390x_nistp##bits##_mu
2020-01-24 12:52:58 +01:00
S390X_SIZE_P##bits); \
} \
\
+static ECDSA_SIG *ecdsa_s390x_nistp##bits##_sign_sig(const unsigned \
+ char *dgst, \
+ int dgstlen, \
+ const BIGNUM *kinv,\
+ const BIGNUM *r, \
+ EC_KEY *eckey) \
+{ \
+ return ecdsa_s390x_nistp_sign_sig(dgst, dgstlen, kinv, r, eckey, \
+ S390X_ECDSA_SIGN_P##bits, \
+ S390X_SIZE_P##bits); \
+} \
+ \
+static int ecdsa_s390x_nistp##bits##_verify_sig(const \
+ unsigned char *dgst, \
+ int dgstlen, \
+ const ECDSA_SIG *sig, \
+ EC_KEY *eckey) \
+{ \
+ return ecdsa_s390x_nistp_verify_sig(dgst, dgstlen, sig, eckey, \
+ S390X_ECDSA_VERIFY_P##bits, \
+ S390X_SIZE_P##bits); \
+} \
+ \
const EC_METHOD *EC_GFp_s390x_nistp##bits##_method(void) \
{ \
static const EC_METHOD EC_GFp_s390x_nistp##bits##_meth = { \
Accepting request 786956 from home:vitezslav_cizek:branches:security:tls - Update to 1.1.1e * Properly detect EOF while reading in libssl. Previously if we hit an EOF while reading in libssl then we would report an error back to the application (SSL_ERROR_SYSCALL) but errno would be 0. We now add an error to the stack (which means we instead return SSL_ERROR_SSL) and therefore give a hint as to what went wrong. * Check that ed25519 and ed448 are allowed by the security level. Previously signature algorithms not using an MD were not being checked that they were allowed by the security level. * Fixed SSL_get_servername() behaviour. The behaviour of SSL_get_servername() was not quite right. The behaviour was not consistent between resumption and normal handshakes, and also not quite consistent with historical behaviour. The behaviour in various scenarios has been clarified and it has been updated to make it match historical behaviour as closely as possible. * Corrected the documentation of the return values from the EVP_DigestSign* set of functions. The documentation mentioned negative values for some errors, but this was never the case, so the mention of negative values was removed. * Added a new method to gather entropy on VMS, based on SYS$GET_ENTROPY. The presence of this system service is determined at run-time. * Added newline escaping functionality to a filename when using openssl dgst. This output format is to replicate the output format found in the '*sum' checksum programs. This aims to preserve backward compatibility. * Print all values for a PKCS#12 attribute with 'openssl pkcs12', not just the first value. - Update bunch of patches as the internal crypto headers got reorganized - drop openssl-1_1-CVE-2019-1551.patch (upstream) - openssl dgst: default to SHA256 only when called without a digest, OBS-URL: https://build.opensuse.org/request/show/786956 OBS-URL: https://build.opensuse.org/package/show/security:tls/openssl-1_1?expand=0&rev=65
2020-03-20 18:43:35 +01:00
@@ -176,8 +366,8 @@ const EC_METHOD *EC_GFp_s390x_nistp##bit
2020-01-24 12:52:58 +01:00
NULL, /* keyfinish */ \
ecdh_simple_compute_key, \
ecdsa_simple_sign_setup, \
- ecdsa_simple_sign_sig, \
- ecdsa_simple_verify_sig, \
+ ecdsa_s390x_nistp##bits##_sign_sig, \
+ ecdsa_s390x_nistp##bits##_verify_sig, \
NULL, /* field_inverse_mod_ord */ \
ec_GFp_simple_blind_coordinates, \
ec_GFp_simple_ladder_pre, \
Accepting request 786956 from home:vitezslav_cizek:branches:security:tls - Update to 1.1.1e * Properly detect EOF while reading in libssl. Previously if we hit an EOF while reading in libssl then we would report an error back to the application (SSL_ERROR_SYSCALL) but errno would be 0. We now add an error to the stack (which means we instead return SSL_ERROR_SSL) and therefore give a hint as to what went wrong. * Check that ed25519 and ed448 are allowed by the security level. Previously signature algorithms not using an MD were not being checked that they were allowed by the security level. * Fixed SSL_get_servername() behaviour. The behaviour of SSL_get_servername() was not quite right. The behaviour was not consistent between resumption and normal handshakes, and also not quite consistent with historical behaviour. The behaviour in various scenarios has been clarified and it has been updated to make it match historical behaviour as closely as possible. * Corrected the documentation of the return values from the EVP_DigestSign* set of functions. The documentation mentioned negative values for some errors, but this was never the case, so the mention of negative values was removed. * Added a new method to gather entropy on VMS, based on SYS$GET_ENTROPY. The presence of this system service is determined at run-time. * Added newline escaping functionality to a filename when using openssl dgst. This output format is to replicate the output format found in the '*sum' checksum programs. This aims to preserve backward compatibility. * Print all values for a PKCS#12 attribute with 'openssl pkcs12', not just the first value. - Update bunch of patches as the internal crypto headers got reorganized - drop openssl-1_1-CVE-2019-1551.patch (upstream) - openssl dgst: default to SHA256 only when called without a digest, OBS-URL: https://build.opensuse.org/request/show/786956 OBS-URL: https://build.opensuse.org/package/show/security:tls/openssl-1_1?expand=0&rev=65
2020-03-20 18:43:35 +01:00
@@ -186,8 +376,12 @@ const EC_METHOD *EC_GFp_s390x_nistp##bit
2020-01-24 12:52:58 +01:00
}; \
static const EC_METHOD *ret; \
\
- if (OPENSSL_s390xcap_P.pcc[1] \
- & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_P##bits)) \
+ if ((OPENSSL_s390xcap_P.pcc[1] \
+ & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_P##bits)) \
+ && (OPENSSL_s390xcap_P.kdsa[0] \
+ & S390X_CAPBIT(S390X_ECDSA_VERIFY_P##bits)) \
+ && (OPENSSL_s390xcap_P.kdsa[0] \
+ & S390X_CAPBIT(S390X_ECDSA_SIGN_P##bits))) \
ret = &EC_GFp_s390x_nistp##bits##_meth; \
else \
ret = EC_GFp_mont_method(); \
Accepting request 786956 from home:vitezslav_cizek:branches:security:tls - Update to 1.1.1e * Properly detect EOF while reading in libssl. Previously if we hit an EOF while reading in libssl then we would report an error back to the application (SSL_ERROR_SYSCALL) but errno would be 0. We now add an error to the stack (which means we instead return SSL_ERROR_SSL) and therefore give a hint as to what went wrong. * Check that ed25519 and ed448 are allowed by the security level. Previously signature algorithms not using an MD were not being checked that they were allowed by the security level. * Fixed SSL_get_servername() behaviour. The behaviour of SSL_get_servername() was not quite right. The behaviour was not consistent between resumption and normal handshakes, and also not quite consistent with historical behaviour. The behaviour in various scenarios has been clarified and it has been updated to make it match historical behaviour as closely as possible. * Corrected the documentation of the return values from the EVP_DigestSign* set of functions. The documentation mentioned negative values for some errors, but this was never the case, so the mention of negative values was removed. * Added a new method to gather entropy on VMS, based on SYS$GET_ENTROPY. The presence of this system service is determined at run-time. * Added newline escaping functionality to a filename when using openssl dgst. This output format is to replicate the output format found in the '*sum' checksum programs. This aims to preserve backward compatibility. * Print all values for a PKCS#12 attribute with 'openssl pkcs12', not just the first value. - Update bunch of patches as the internal crypto headers got reorganized - drop openssl-1_1-CVE-2019-1551.patch (upstream) - openssl dgst: default to SHA256 only when called without a digest, OBS-URL: https://build.opensuse.org/request/show/786956 OBS-URL: https://build.opensuse.org/package/show/security:tls/openssl-1_1?expand=0&rev=65
2020-03-20 18:43:35 +01:00
Index: openssl-1.1.1e/crypto/err/openssl.txt
===================================================================
--- openssl-1.1.1e.orig/crypto/err/openssl.txt 2020-03-20 13:13:44.618571104 +0100
+++ openssl-1.1.1e/crypto/err/openssl.txt 2020-03-20 13:14:02.446664907 +0100
@@ -499,6 +499,8 @@ EC_F_ECDSA_VERIFY:253:ECDSA_verify
2020-01-24 12:52:58 +01:00
EC_F_ECDSA_SIMPLE_SIGN_SETUP:310:ecdsa_simple_sign_setup
EC_F_ECDSA_SIMPLE_SIGN_SIG:311:ecdsa_simple_sign_sig
EC_F_ECDSA_SIMPLE_VERIFY_SIG:312:ecdsa_simple_verify_sig
+EC_F_ECDSA_S390X_NISTP_SIGN_SIG:313:ecdsa_s390x_nistp_sign_sig
+EC_F_ECDSA_S390X_NISTP_VERIFY_SIG:314:ecdsa_s390x_nistp_verify_sig
EC_F_ECD_ITEM_VERIFY:270:ecd_item_verify
EC_F_ECKEY_PARAM2TYPE:223:eckey_param2type
EC_F_ECKEY_PARAM_DECODE:212:eckey_param_decode