]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/ec/ecp_s390x_nistp.c
2 * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
12 #include <openssl/err.h>
14 #include "s390x_arch.h"
16 /* Size of parameter blocks */
17 #define S390X_SIZE_PARAM 4096
19 /* Size of fields in parameter blocks */
20 #define S390X_SIZE_P256 32
21 #define S390X_SIZE_P384 48
22 #define S390X_SIZE_P521 80
24 /* Offsets of fields in PCC parameter blocks */
25 #define S390X_OFF_RES_X(n) (0 * n)
26 #define S390X_OFF_RES_Y(n) (1 * n)
27 #define S390X_OFF_SRC_X(n) (2 * n)
28 #define S390X_OFF_SRC_Y(n) (3 * n)
29 #define S390X_OFF_SCALAR(n) (4 * n)
31 static int ec_GFp_s390x_nistp_mul(const EC_GROUP
*group
, EC_POINT
*r
,
33 size_t num
, const EC_POINT
*points
[],
34 const BIGNUM
*scalars
[],
35 BN_CTX
*ctx
, unsigned int fc
, int len
)
37 unsigned char param
[S390X_SIZE_PARAM
];
39 const EC_POINT
*point_ptr
= NULL
;
40 const BIGNUM
*scalar_ptr
= NULL
;
41 BN_CTX
*new_ctx
= NULL
;
45 ctx
= new_ctx
= BN_CTX_new_ex(group
->libctx
);
54 if (x
== NULL
|| y
== NULL
) {
60 * Use PCC for EC keygen and ECDH key derivation:
61 * scalar * generator and scalar * peer public key,
62 * scalar in [0,order).
64 if ((scalar
!= NULL
&& num
== 0 && BN_is_negative(scalar
) == 0)
65 || (scalar
== NULL
&& num
== 1 && BN_is_negative(scalars
[0]) == 0)) {
68 point_ptr
= EC_GROUP_get0_generator(group
);
71 point_ptr
= points
[0];
72 scalar_ptr
= scalars
[0];
75 if (EC_POINT_is_at_infinity(group
, point_ptr
) == 1
76 || BN_is_zero(scalar_ptr
)) {
77 rc
= EC_POINT_set_to_infinity(group
, r
);
81 memset(¶m
, 0, sizeof(param
));
83 if (group
->meth
->point_get_affine_coordinates(group
, point_ptr
,
85 || BN_bn2binpad(x
, param
+ S390X_OFF_SRC_X(len
), len
) == -1
86 || BN_bn2binpad(y
, param
+ S390X_OFF_SRC_Y(len
), len
) == -1
87 || BN_bn2binpad(scalar_ptr
,
88 param
+ S390X_OFF_SCALAR(len
), len
) == -1
89 || s390x_pcc(fc
, param
) != 0
90 || BN_bin2bn(param
+ S390X_OFF_RES_X(len
), len
, x
) == NULL
91 || BN_bin2bn(param
+ S390X_OFF_RES_Y(len
), len
, y
) == NULL
92 || group
->meth
->point_set_affine_coordinates(group
, r
,
100 /* Otherwise use default. */
102 rc
= ec_wNAF_mul(group
, r
, scalar
, num
, points
, scalars
, ctx
);
103 OPENSSL_cleanse(param
, sizeof(param
));
105 BN_CTX_free(new_ctx
);
109 #define EC_GFP_S390X_NISTP_METHOD(bits) \
111 static int ec_GFp_s390x_nistp##bits##_mul(const EC_GROUP *group, \
113 const BIGNUM *scalar, \
115 const EC_POINT *points[], \
116 const BIGNUM *scalars[], \
119 return ec_GFp_s390x_nistp_mul(group, r, scalar, num, points, \
121 S390X_SCALAR_MULTIPLY_P##bits, \
122 S390X_SIZE_P##bits); \
125 const EC_METHOD *EC_GFp_s390x_nistp##bits##_method(void) \
127 static const EC_METHOD EC_GFp_s390x_nistp##bits##_meth = { \
128 EC_FLAGS_DEFAULT_OCT, \
129 NID_X9_62_prime_field, \
130 ec_GFp_simple_group_init, \
131 ec_GFp_simple_group_finish, \
132 ec_GFp_simple_group_clear_finish, \
133 ec_GFp_simple_group_copy, \
134 ec_GFp_simple_group_set_curve, \
135 ec_GFp_simple_group_get_curve, \
136 ec_GFp_simple_group_get_degree, \
137 ec_group_simple_order_bits, \
138 ec_GFp_simple_group_check_discriminant, \
139 ec_GFp_simple_point_init, \
140 ec_GFp_simple_point_finish, \
141 ec_GFp_simple_point_clear_finish, \
142 ec_GFp_simple_point_copy, \
143 ec_GFp_simple_point_set_to_infinity, \
144 ec_GFp_simple_set_Jprojective_coordinates_GFp, \
145 ec_GFp_simple_get_Jprojective_coordinates_GFp, \
146 ec_GFp_simple_point_set_affine_coordinates, \
147 ec_GFp_simple_point_get_affine_coordinates, \
148 NULL, /* point_set_compressed_coordinates */ \
149 NULL, /* point2oct */ \
150 NULL, /* oct2point */ \
153 ec_GFp_simple_invert, \
154 ec_GFp_simple_is_at_infinity, \
155 ec_GFp_simple_is_on_curve, \
157 ec_GFp_simple_make_affine, \
158 ec_GFp_simple_points_make_affine, \
159 ec_GFp_s390x_nistp##bits##_mul, \
160 NULL, /* precompute_mult */ \
161 NULL, /* have_precompute_mult */ \
162 ec_GFp_simple_field_mul, \
163 ec_GFp_simple_field_sqr, \
164 NULL, /* field_div */ \
165 ec_GFp_simple_field_inv, \
166 NULL, /* field_encode */ \
167 NULL, /* field_decode */ \
168 NULL, /* field_set_to_one */ \
169 ec_key_simple_priv2oct, \
170 ec_key_simple_oct2priv, \
171 NULL, /* set_private */ \
172 ec_key_simple_generate_key, \
173 ec_key_simple_check_key, \
174 ec_key_simple_generate_public_key, \
175 NULL, /* keycopy */ \
176 NULL, /* keyfinish */ \
177 ecdh_simple_compute_key, \
178 ecdsa_simple_sign_setup, \
179 ecdsa_simple_sign_sig, \
180 ecdsa_simple_verify_sig, \
181 NULL, /* field_inverse_mod_ord */ \
182 ec_GFp_simple_blind_coordinates, \
183 ec_GFp_simple_ladder_pre, \
184 ec_GFp_simple_ladder_step, \
185 ec_GFp_simple_ladder_post \
187 static const EC_METHOD *ret; \
189 if (OPENSSL_s390xcap_P.pcc[1] \
190 & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_P##bits)) \
191 ret = &EC_GFp_s390x_nistp##bits##_meth; \
193 ret = EC_GFp_mont_method(); \
198 EC_GFP_S390X_NISTP_METHOD(256)
199 EC_GFP_S390X_NISTP_METHOD(384)
200 EC_GFP_S390X_NISTP_METHOD(521)