]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/ec/ecp_s390x_nistp.c
Enable curve-spefific ECDSA implementations via EC_METHOD
[thirdparty/openssl.git] / crypto / ec / ecp_s390x_nistp.c
CommitLineData
1461e667
PS
1/*
2 * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
3 *
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
8 */
9
10#include <stdlib.h>
11#include <string.h>
12#include <openssl/err.h>
13#include "ec_lcl.h"
14#include "s390x_arch.h"
15
16/* Size of parameter blocks */
17#define S390X_SIZE_PARAM 4096
18
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
23
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)
30
31static int ec_GFp_s390x_nistp_mul(const EC_GROUP *group, EC_POINT *r,
32 const BIGNUM *scalar,
33 size_t num, const EC_POINT *points[],
34 const BIGNUM *scalars[],
35 BN_CTX *ctx, unsigned int fc, int len)
36{
37 unsigned char param[S390X_SIZE_PARAM];
38 BIGNUM *x, *y;
39 const EC_POINT *point_ptr = NULL;
40 const BIGNUM *scalar_ptr = NULL;
41 BN_CTX *new_ctx = NULL;
42 int rc = -1;
43
44 if (ctx == NULL) {
45 ctx = new_ctx = BN_CTX_new_ex(group->libctx);
46 if (ctx == NULL)
47 return 0;
48 }
49
50 BN_CTX_start(ctx);
51
52 x = BN_CTX_get(ctx);
53 y = BN_CTX_get(ctx);
54 if (x == NULL || y == NULL) {
55 rc = 0;
56 goto ret;
57 }
58
59 /*
60 * Use PCC for EC keygen and ECDH key derivation:
61 * scalar * generator and scalar * peer public key,
62 * scalar in [0,order).
63 */
64 if ((scalar != NULL && num == 0 && BN_is_negative(scalar) == 0)
65 || (scalar == NULL && num == 1 && BN_is_negative(scalars[0]) == 0)) {
66
67 if (num == 0) {
68 point_ptr = EC_GROUP_get0_generator(group);
69 scalar_ptr = scalar;
70 } else {
71 point_ptr = points[0];
72 scalar_ptr = scalars[0];
73 }
74
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);
78 goto ret;
79 }
80
81 memset(&param, 0, sizeof(param));
82
83 if (group->meth->point_get_affine_coordinates(group, point_ptr,
84 x, y, ctx) != 1
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,
93 x, y, ctx) != 1)
94 goto ret;
95
96 rc = 1;
97 }
98
99ret:
100 /* Otherwise use default. */
101 if (rc == -1)
102 rc = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
103 OPENSSL_cleanse(param, sizeof(param));
104 BN_CTX_end(ctx);
105 BN_CTX_free(new_ctx);
106 return rc;
107}
108
109#define EC_GFP_S390X_NISTP_METHOD(bits) \
110 \
111static int ec_GFp_s390x_nistp##bits##_mul(const EC_GROUP *group, \
112 EC_POINT *r, \
113 const BIGNUM *scalar, \
114 size_t num, \
115 const EC_POINT *points[], \
116 const BIGNUM *scalars[], \
117 BN_CTX *ctx) \
118{ \
119 return ec_GFp_s390x_nistp_mul(group, r, scalar, num, points, \
120 scalars, ctx, \
121 S390X_SCALAR_MULTIPLY_P##bits, \
122 S390X_SIZE_P##bits); \
123} \
124 \
125const EC_METHOD *EC_GFp_s390x_nistp##bits##_method(void) \
126{ \
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 */ \
151 ec_GFp_simple_add, \
152 ec_GFp_simple_dbl, \
153 ec_GFp_simple_invert, \
154 ec_GFp_simple_is_at_infinity, \
155 ec_GFp_simple_is_on_curve, \
156 ec_GFp_simple_cmp, \
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, \
9bf682f6
PS
178 ecdsa_simple_sign_setup, \
179 ecdsa_simple_sign_sig, \
180 ecdsa_simple_verify_sig, \
1461e667
PS
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 \
186 }; \
187 static const EC_METHOD *ret; \
188 \
189 if (OPENSSL_s390xcap_P.pcc[1] \
190 & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_P##bits)) \
191 ret = &EC_GFp_s390x_nistp##bits##_meth; \
192 else \
193 ret = EC_GFp_mont_method(); \
194 \
195 return ret; \
196}
197
198EC_GFP_S390X_NISTP_METHOD(256)
199EC_GFP_S390X_NISTP_METHOD(384)
200EC_GFP_S390X_NISTP_METHOD(521)