diff options
Diffstat (limited to 'crypto/ec/ecp_s390x_nistp.c')
| -rw-r--r-- | crypto/ec/ecp_s390x_nistp.c | 323 |
1 files changed, 171 insertions, 152 deletions
diff --git a/crypto/ec/ecp_s390x_nistp.c b/crypto/ec/ecp_s390x_nistp.c index 0c10196ea34e..bfcbbe171662 100644 --- a/crypto/ec/ecp_s390x_nistp.c +++ b/crypto/ec/ecp_s390x_nistp.c @@ -21,34 +21,36 @@ #include "s390x_arch.h" /* Size of parameter blocks */ -#define S390X_SIZE_PARAM 4096 +#define S390X_SIZE_PARAM 4096 /* Size of fields in parameter blocks */ -#define S390X_SIZE_P256 32 -#define S390X_SIZE_P384 48 -#define S390X_SIZE_P521 80 +#define S390X_SIZE_P256 32 +#define S390X_SIZE_P384 48 +#define S390X_SIZE_P521 80 /* Offsets of fields in PCC parameter blocks */ -#define S390X_OFF_RES_X(n) (0 * n) -#define S390X_OFF_RES_Y(n) (1 * n) -#define S390X_OFF_SRC_X(n) (2 * n) -#define S390X_OFF_SRC_Y(n) (3 * n) -#define S390X_OFF_SCALAR(n) (4 * n) +#define S390X_OFF_RES_X(n) (0 * n) +#define S390X_OFF_RES_Y(n) (1 * n) +#define S390X_OFF_SRC_X(n) (2 * n) +#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) +#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) + +#define S390X_PAD(n) (n == 80 ? 14 : 0) static int ec_GFp_s390x_nistp_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, - size_t num, const EC_POINT *points[], - const BIGNUM *scalars[], - BN_CTX *ctx, unsigned int fc, int len) + const BIGNUM *scalar, + size_t num, const EC_POINT *points[], + const BIGNUM *scalars[], + BN_CTX *ctx, unsigned int fc, int len) { unsigned char param[S390X_SIZE_PARAM]; BIGNUM *x, *y; @@ -97,16 +99,19 @@ static int ec_GFp_s390x_nistp_mul(const EC_GROUP *group, EC_POINT *r, memset(¶m, 0, sizeof(param)); if (group->meth->point_get_affine_coordinates(group, point_ptr, - x, y, ctx) != 1 + x, y, ctx) + != 1 || BN_bn2binpad(x, param + S390X_OFF_SRC_X(len), len) == -1 || BN_bn2binpad(y, param + S390X_OFF_SRC_Y(len), len) == -1 || BN_bn2binpad(scalar_ptr, - param + S390X_OFF_SCALAR(len), len) == -1 + param + S390X_OFF_SCALAR(len), len) + == -1 || s390x_pcc(fc, param) != 0 || BN_bin2bn(param + S390X_OFF_RES_X(len), len, x) == NULL || BN_bin2bn(param + S390X_OFF_RES_Y(len), len, y) == NULL || group->meth->point_set_affine_coordinates(group, r, - x, y, ctx) != 1) + x, y, ctx) + != 1) goto ret; rc = 1; @@ -123,11 +128,11 @@ ret: } 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) + 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; @@ -183,11 +188,12 @@ static ECDSA_SIG *ecdsa_s390x_nistp_sign_sig(const unsigned char *dgst, * because kdsa instruction constructs an in-range, invertible nonce * internally implementing counter-measures for RNG weakness. */ - if (RAND_priv_bytes_ex(eckey->libctx, param + S390X_OFF_RN(len), - (size_t)len, 0) != 1) { - ERR_raise(ERR_LIB_EC, EC_R_RANDOM_NUMBER_GENERATION_FAILED); - goto ret; - } + if (RAND_priv_bytes_ex(eckey->libctx, param + S390X_OFF_RN(len), + (size_t)len, 0) + != 1) { + ERR_raise(ERR_LIB_EC, EC_R_RANDOM_NUMBER_GENERATION_FAILED); + goto ret; + } } else { /* Reconstruct k = (k^-1)^-1. */ if (ossl_ec_group_do_inverse_ord(group, k, kinv, NULL) == 0 @@ -222,8 +228,8 @@ ret: } 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) + const ECDSA_SIG *sig, EC_KEY *eckey, + unsigned int fc, int len) { unsigned char param[S390X_SIZE_PARAM]; int rc = -1; @@ -264,136 +270,149 @@ static int ecdsa_s390x_nistp_verify_sig(const unsigned char *dgst, int dgstlen, off = len - (dgstlen > len ? len : dgstlen); memcpy(param + S390X_OFF_H(len) + off, dgst, len - off); + /* Check for invalid malformed signatures (r/s negative or too large) */ + if (BN_is_negative(sig->r) || BN_is_negative(sig->s) + || BN_bn2binpad(sig->r, param + S390X_OFF_R(len) + S390X_PAD(len), + len - S390X_PAD(len)) + == -1 + || BN_bn2binpad(sig->s, param + S390X_OFF_S(len) + S390X_PAD(len), + len - S390X_PAD(len)) + == -1) { + ERR_raise(ERR_LIB_EC, EC_R_BAD_SIGNATURE); + rc = 0; + goto ret; + } + 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 + x, y, ctx) + != 1 || BN_bn2binpad(x, param + S390X_OFF_X(len), len) == -1 || BN_bn2binpad(y, param + S390X_OFF_Y(len), len) == -1) { ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); goto ret; } - rc = s390x_kdsa(fc, param, NULL, 0) == 0 ? 1 : 0; + rc = s390x_kdsa(fc, param, NULL, 0); + if (rc == 2) + ERR_raise(ERR_LIB_EC, EC_R_BAD_SIGNATURE); + rc = rc == 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, \ - EC_POINT *r, \ - const BIGNUM *scalar, \ - size_t num, \ - const EC_POINT *points[], \ - const BIGNUM *scalars[], \ - BN_CTX *ctx) \ -{ \ - return ec_GFp_s390x_nistp_mul(group, r, scalar, num, points, \ - scalars, ctx, \ - S390X_SCALAR_MULTIPLY_P##bits, \ - 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 = { \ - EC_FLAGS_DEFAULT_OCT, \ - NID_X9_62_prime_field, \ - ossl_ec_GFp_simple_group_init, \ - ossl_ec_GFp_simple_group_finish, \ - ossl_ec_GFp_simple_group_clear_finish, \ - ossl_ec_GFp_simple_group_copy, \ - ossl_ec_GFp_simple_group_set_curve, \ - ossl_ec_GFp_simple_group_get_curve, \ - ossl_ec_GFp_simple_group_get_degree, \ - ossl_ec_group_simple_order_bits, \ - ossl_ec_GFp_simple_group_check_discriminant, \ - ossl_ec_GFp_simple_point_init, \ - ossl_ec_GFp_simple_point_finish, \ - ossl_ec_GFp_simple_point_clear_finish, \ - ossl_ec_GFp_simple_point_copy, \ - ossl_ec_GFp_simple_point_set_to_infinity, \ - ossl_ec_GFp_simple_point_set_affine_coordinates, \ - ossl_ec_GFp_simple_point_get_affine_coordinates, \ - NULL, /* point_set_compressed_coordinates */ \ - NULL, /* point2oct */ \ - NULL, /* oct2point */ \ - ossl_ec_GFp_simple_add, \ - ossl_ec_GFp_simple_dbl, \ - ossl_ec_GFp_simple_invert, \ - ossl_ec_GFp_simple_is_at_infinity, \ - ossl_ec_GFp_simple_is_on_curve, \ - ossl_ec_GFp_simple_cmp, \ - ossl_ec_GFp_simple_make_affine, \ - ossl_ec_GFp_simple_points_make_affine, \ - ec_GFp_s390x_nistp##bits##_mul, \ - NULL, /* precompute_mult */ \ - NULL, /* have_precompute_mult */ \ - ossl_ec_GFp_simple_field_mul, \ - ossl_ec_GFp_simple_field_sqr, \ - NULL, /* field_div */ \ - ossl_ec_GFp_simple_field_inv, \ - NULL, /* field_encode */ \ - NULL, /* field_decode */ \ - NULL, /* field_set_to_one */ \ - ossl_ec_key_simple_priv2oct, \ - ossl_ec_key_simple_oct2priv, \ - NULL, /* set_private */ \ - ossl_ec_key_simple_generate_key, \ - ossl_ec_key_simple_check_key, \ - ossl_ec_key_simple_generate_public_key, \ - NULL, /* keycopy */ \ - NULL, /* keyfinish */ \ - ossl_ecdh_simple_compute_key, \ - ossl_ecdsa_simple_sign_setup, \ - ecdsa_s390x_nistp##bits##_sign_sig, \ - ecdsa_s390x_nistp##bits##_verify_sig, \ - NULL, /* field_inverse_mod_ord */ \ - ossl_ec_GFp_simple_blind_coordinates, \ - ossl_ec_GFp_simple_ladder_pre, \ - ossl_ec_GFp_simple_ladder_step, \ - ossl_ec_GFp_simple_ladder_post \ - }; \ - static const EC_METHOD *ret; \ - \ - 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(); \ - \ - return ret; \ -} +#define EC_GFP_S390X_NISTP_METHOD(bits) \ + \ + static int ec_GFp_s390x_nistp##bits##_mul(const EC_GROUP *group, \ + EC_POINT *r, \ + const BIGNUM *scalar, \ + size_t num, \ + const EC_POINT *points[], \ + const BIGNUM *scalars[], \ + BN_CTX *ctx) \ + { \ + return ec_GFp_s390x_nistp_mul(group, r, scalar, num, points, \ + scalars, ctx, \ + S390X_SCALAR_MULTIPLY_P##bits, \ + 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 = { \ + EC_FLAGS_DEFAULT_OCT, \ + NID_X9_62_prime_field, \ + ossl_ec_GFp_simple_group_init, \ + ossl_ec_GFp_simple_group_finish, \ + ossl_ec_GFp_simple_group_clear_finish, \ + ossl_ec_GFp_simple_group_copy, \ + ossl_ec_GFp_simple_group_set_curve, \ + ossl_ec_GFp_simple_group_get_curve, \ + ossl_ec_GFp_simple_group_get_degree, \ + ossl_ec_group_simple_order_bits, \ + ossl_ec_GFp_simple_group_check_discriminant, \ + ossl_ec_GFp_simple_point_init, \ + ossl_ec_GFp_simple_point_finish, \ + ossl_ec_GFp_simple_point_clear_finish, \ + ossl_ec_GFp_simple_point_copy, \ + ossl_ec_GFp_simple_point_set_to_infinity, \ + ossl_ec_GFp_simple_point_set_affine_coordinates, \ + ossl_ec_GFp_simple_point_get_affine_coordinates, \ + NULL, /* point_set_compressed_coordinates */ \ + NULL, /* point2oct */ \ + NULL, /* oct2point */ \ + ossl_ec_GFp_simple_add, \ + ossl_ec_GFp_simple_dbl, \ + ossl_ec_GFp_simple_invert, \ + ossl_ec_GFp_simple_is_at_infinity, \ + ossl_ec_GFp_simple_is_on_curve, \ + ossl_ec_GFp_simple_cmp, \ + ossl_ec_GFp_simple_make_affine, \ + ossl_ec_GFp_simple_points_make_affine, \ + ec_GFp_s390x_nistp##bits##_mul, \ + NULL, /* precompute_mult */ \ + NULL, /* have_precompute_mult */ \ + ossl_ec_GFp_simple_field_mul, \ + ossl_ec_GFp_simple_field_sqr, \ + NULL, /* field_div */ \ + ossl_ec_GFp_simple_field_inv, \ + NULL, /* field_encode */ \ + NULL, /* field_decode */ \ + NULL, /* field_set_to_one */ \ + ossl_ec_key_simple_priv2oct, \ + ossl_ec_key_simple_oct2priv, \ + NULL, /* set_private */ \ + ossl_ec_key_simple_generate_key, \ + ossl_ec_key_simple_check_key, \ + ossl_ec_key_simple_generate_public_key, \ + NULL, /* keycopy */ \ + NULL, /* keyfinish */ \ + ossl_ecdh_simple_compute_key, \ + ossl_ecdsa_simple_sign_setup, \ + ecdsa_s390x_nistp##bits##_sign_sig, \ + ecdsa_s390x_nistp##bits##_verify_sig, \ + NULL, /* field_inverse_mod_ord */ \ + ossl_ec_GFp_simple_blind_coordinates, \ + ossl_ec_GFp_simple_ladder_pre, \ + ossl_ec_GFp_simple_ladder_step, \ + ossl_ec_GFp_simple_ladder_post \ + }; \ + static const EC_METHOD *ret; \ + \ + 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(); \ + \ + return ret; \ + } EC_GFP_S390X_NISTP_METHOD(256) EC_GFP_S390X_NISTP_METHOD(384) |
