diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libcrypto/gost/gost89imit_pmeth.c | 12 | ||||
-rw-r--r-- | src/lib/libcrypto/gost/gost_locl.h | 4 | ||||
-rw-r--r-- | src/lib/libcrypto/gost/gostr341001.c | 256 | ||||
-rw-r--r-- | src/lib/libcrypto/gost/gostr341001_ameth.c | 222 | ||||
-rw-r--r-- | src/lib/libcrypto/gost/gostr341001_key.c | 28 | ||||
-rw-r--r-- | src/lib/libcrypto/gost/gostr341001_pmeth.c | 253 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/gost/gost89imit_pmeth.c | 12 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/gost/gost_locl.h | 4 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/gost/gostr341001.c | 256 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/gost/gostr341001_ameth.c | 222 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/gost/gostr341001_key.c | 28 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/gost/gostr341001_pmeth.c | 253 |
12 files changed, 976 insertions, 574 deletions
diff --git a/src/lib/libcrypto/gost/gost89imit_pmeth.c b/src/lib/libcrypto/gost/gost89imit_pmeth.c index fa79abf0af..00eaf1decc 100644 --- a/src/lib/libcrypto/gost/gost89imit_pmeth.c +++ b/src/lib/libcrypto/gost/gost89imit_pmeth.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: gost89imit_pmeth.c,v 1.2 2014/11/09 23:06:52 miod Exp $ */ | 1 | /* $OpenBSD: gost89imit_pmeth.c,v 1.3 2014/11/13 20:29:55 miod Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> |
4 | * Copyright (c) 2005-2006 Cryptocom LTD | 4 | * Copyright (c) 2005-2006 Cryptocom LTD |
@@ -115,20 +115,26 @@ pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) | |||
115 | } | 115 | } |
116 | 116 | ||
117 | keydata = malloc(32); | 117 | keydata = malloc(32); |
118 | if (keydata == NULL) { | ||
119 | GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN, ERR_R_MALLOC_FAILURE); | ||
120 | return 0; | ||
121 | } | ||
118 | memcpy(keydata, data->key, 32); | 122 | memcpy(keydata, data->key, 32); |
119 | EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata); | 123 | EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata); |
120 | 124 | ||
121 | return 1; | 125 | return 1; |
122 | } | 126 | } |
123 | 127 | ||
124 | static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) | 128 | static int |
129 | pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) | ||
125 | { | 130 | { |
126 | struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); | 131 | struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); |
127 | 132 | ||
128 | switch (type) { | 133 | switch (type) { |
129 | case EVP_PKEY_CTRL_MD: | 134 | case EVP_PKEY_CTRL_MD: |
130 | if (EVP_MD_type(p2) != NID_id_Gost28147_89_MAC) { | 135 | if (EVP_MD_type(p2) != NID_id_Gost28147_89_MAC) { |
131 | GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_DIGEST_TYPE); | 136 | GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, |
137 | GOST_R_INVALID_DIGEST_TYPE); | ||
132 | return 0; | 138 | return 0; |
133 | } | 139 | } |
134 | data->md = p2; | 140 | data->md = p2; |
diff --git a/src/lib/libcrypto/gost/gost_locl.h b/src/lib/libcrypto/gost/gost_locl.h index 202ba39688..9036f59771 100644 --- a/src/lib/libcrypto/gost/gost_locl.h +++ b/src/lib/libcrypto/gost/gost_locl.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: gost_locl.h,v 1.2 2014/11/09 19:27:29 miod Exp $ */ | 1 | /* $OpenBSD: gost_locl.h,v 1.3 2014/11/13 20:29:55 miod Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> |
4 | * Copyright (c) 2005-2006 Cryptocom LTD | 4 | * Copyright (c) 2005-2006 Cryptocom LTD |
@@ -99,7 +99,7 @@ extern int gost2001_compute_public(GOST_KEY *ec); | |||
99 | extern ECDSA_SIG *gost2001_do_sign(BIGNUM *md, GOST_KEY *eckey); | 99 | extern ECDSA_SIG *gost2001_do_sign(BIGNUM *md, GOST_KEY *eckey); |
100 | extern int gost2001_do_verify(BIGNUM *md, ECDSA_SIG *sig, GOST_KEY *ec); | 100 | extern int gost2001_do_verify(BIGNUM *md, ECDSA_SIG *sig, GOST_KEY *ec); |
101 | extern int gost2001_keygen(GOST_KEY *ec); | 101 | extern int gost2001_keygen(GOST_KEY *ec); |
102 | extern void VKO_compute_key(BIGNUM *X, BIGNUM *Y, const GOST_KEY *pkey, | 102 | extern int VKO_compute_key(BIGNUM *X, BIGNUM *Y, const GOST_KEY *pkey, |
103 | GOST_KEY *priv_key, const BIGNUM *ukm); | 103 | GOST_KEY *priv_key, const BIGNUM *ukm); |
104 | extern BIGNUM *GOST_le2bn(const unsigned char *buf, size_t len, BIGNUM *bn); | 104 | extern BIGNUM *GOST_le2bn(const unsigned char *buf, size_t len, BIGNUM *bn); |
105 | extern int GOST_bn2le(BIGNUM *bn, unsigned char *buf, int len); | 105 | extern int GOST_bn2le(BIGNUM *bn, unsigned char *buf, int len); |
diff --git a/src/lib/libcrypto/gost/gostr341001.c b/src/lib/libcrypto/gost/gostr341001.c index 3c314765f7..171cf1b80a 100644 --- a/src/lib/libcrypto/gost/gostr341001.c +++ b/src/lib/libcrypto/gost/gostr341001.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: gostr341001.c,v 1.1 2014/11/09 19:17:13 miod Exp $ */ | 1 | /* $OpenBSD: gostr341001.c,v 1.2 2014/11/13 20:29:55 miod Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> |
4 | * Copyright (c) 2005-2006 Cryptocom LTD | 4 | * Copyright (c) 2005-2006 Cryptocom LTD |
@@ -59,10 +59,12 @@ | |||
59 | #include "gost_locl.h" | 59 | #include "gost_locl.h" |
60 | 60 | ||
61 | /* Convert little-endian byte array into bignum */ | 61 | /* Convert little-endian byte array into bignum */ |
62 | BIGNUM *GOST_le2bn(const unsigned char * buf, size_t len, BIGNUM * bn) | 62 | BIGNUM * |
63 | GOST_le2bn(const unsigned char *buf, size_t len, BIGNUM *bn) | ||
63 | { | 64 | { |
64 | unsigned char temp[64]; | 65 | unsigned char temp[64]; |
65 | int i; | 66 | int i; |
67 | |||
66 | if (len > 64) | 68 | if (len > 64) |
67 | return NULL; | 69 | return NULL; |
68 | 70 | ||
@@ -73,7 +75,8 @@ BIGNUM *GOST_le2bn(const unsigned char * buf, size_t len, BIGNUM * bn) | |||
73 | return BN_bin2bn(temp, len, bn); | 75 | return BN_bin2bn(temp, len, bn); |
74 | } | 76 | } |
75 | 77 | ||
76 | int GOST_bn2le(BIGNUM * bn, unsigned char * buf, int len) | 78 | int |
79 | GOST_bn2le(BIGNUM *bn, unsigned char *buf, int len) | ||
77 | { | 80 | { |
78 | unsigned char temp[64]; | 81 | unsigned char temp[64]; |
79 | int i, bytes; | 82 | int i, bytes; |
@@ -93,8 +96,8 @@ int GOST_bn2le(BIGNUM * bn, unsigned char * buf, int len) | |||
93 | return 1; | 96 | return 1; |
94 | } | 97 | } |
95 | 98 | ||
96 | 99 | int | |
97 | int gost2001_compute_public(GOST_KEY * ec) | 100 | gost2001_compute_public(GOST_KEY *ec) |
98 | { | 101 | { |
99 | const EC_GROUP *group = GOST_KEY_get0_group(ec); | 102 | const EC_GROUP *group = GOST_KEY_get0_group(ec); |
100 | EC_POINT *pub_key = NULL; | 103 | EC_POINT *pub_key = NULL; |
@@ -102,36 +105,44 @@ int gost2001_compute_public(GOST_KEY * ec) | |||
102 | BN_CTX *ctx = NULL; | 105 | BN_CTX *ctx = NULL; |
103 | int ok = 0; | 106 | int ok = 0; |
104 | 107 | ||
105 | if (!group) { | 108 | if (group == NULL) { |
106 | GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, | 109 | GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, |
107 | GOST_R_KEY_IS_NOT_INITIALIZED); | 110 | GOST_R_KEY_IS_NOT_INITIALIZED); |
108 | return 0; | 111 | return 0; |
109 | } | 112 | } |
110 | ctx = BN_CTX_new(); | 113 | ctx = BN_CTX_new(); |
114 | if (ctx == NULL) { | ||
115 | GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, | ||
116 | ERR_R_MALLOC_FAILURE); | ||
117 | return 0; | ||
118 | } | ||
111 | BN_CTX_start(ctx); | 119 | BN_CTX_start(ctx); |
112 | if (!(priv_key = GOST_KEY_get0_private_key(ec))) { | 120 | if ((priv_key = GOST_KEY_get0_private_key(ec)) == NULL) |
113 | GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); | ||
114 | goto err; | 121 | goto err; |
115 | } | ||
116 | 122 | ||
117 | pub_key = EC_POINT_new(group); | 123 | pub_key = EC_POINT_new(group); |
118 | if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) { | 124 | if (pub_key == NULL) |
119 | GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); | ||
120 | goto err; | 125 | goto err; |
121 | } | 126 | if (EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx) == 0) |
122 | if (!GOST_KEY_set_public_key(ec, pub_key)) { | ||
123 | GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); | ||
124 | goto err; | 127 | goto err; |
125 | } | 128 | if (GOST_KEY_set_public_key(ec, pub_key) == 0) |
126 | ok = 256; | 129 | goto err; |
130 | ok = 1; | ||
131 | |||
132 | if (ok == 0) { | ||
127 | err: | 133 | err: |
128 | BN_CTX_end(ctx); | 134 | GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); |
135 | } | ||
129 | EC_POINT_free(pub_key); | 136 | EC_POINT_free(pub_key); |
130 | BN_CTX_free(ctx); | 137 | if (ctx != NULL) { |
138 | BN_CTX_end(ctx); | ||
139 | BN_CTX_free(ctx); | ||
140 | } | ||
131 | return ok; | 141 | return ok; |
132 | } | 142 | } |
133 | 143 | ||
134 | ECDSA_SIG *gost2001_do_sign(BIGNUM * md, GOST_KEY * eckey) | 144 | ECDSA_SIG * |
145 | gost2001_do_sign(BIGNUM *md, GOST_KEY *eckey) | ||
135 | { | 146 | { |
136 | ECDSA_SIG *newsig = NULL; | 147 | ECDSA_SIG *newsig = NULL; |
137 | BIGNUM *order = NULL; | 148 | BIGNUM *order = NULL; |
@@ -141,9 +152,15 @@ ECDSA_SIG *gost2001_do_sign(BIGNUM * md, GOST_KEY * eckey) | |||
141 | NULL, *e = NULL; | 152 | NULL, *e = NULL; |
142 | EC_POINT *C = NULL; | 153 | EC_POINT *C = NULL; |
143 | BN_CTX *ctx = BN_CTX_new(); | 154 | BN_CTX *ctx = BN_CTX_new(); |
155 | int ok = 0; | ||
156 | |||
157 | if (ctx == NULL) { | ||
158 | GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
159 | return NULL; | ||
160 | } | ||
144 | BN_CTX_start(ctx); | 161 | BN_CTX_start(ctx); |
145 | newsig = ECDSA_SIG_new(); | 162 | newsig = ECDSA_SIG_new(); |
146 | if (!newsig) { | 163 | if (newsig == NULL) { |
147 | GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE); | 164 | GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE); |
148 | goto err; | 165 | goto err; |
149 | } | 166 | } |
@@ -151,70 +168,88 @@ ECDSA_SIG *gost2001_do_sign(BIGNUM * md, GOST_KEY * eckey) | |||
151 | r = newsig->r; | 168 | r = newsig->r; |
152 | group = GOST_KEY_get0_group(eckey); | 169 | group = GOST_KEY_get0_group(eckey); |
153 | order = BN_CTX_get(ctx); | 170 | order = BN_CTX_get(ctx); |
154 | EC_GROUP_get_order(group, order, ctx); | 171 | if (order == NULL) |
172 | goto err; | ||
173 | if (EC_GROUP_get_order(group, order, ctx) == 0) | ||
174 | goto err; | ||
155 | priv_key = GOST_KEY_get0_private_key(eckey); | 175 | priv_key = GOST_KEY_get0_private_key(eckey); |
156 | e = BN_CTX_get(ctx); | 176 | e = BN_CTX_get(ctx); |
157 | BN_mod(e, md, order, ctx); | 177 | if (e == NULL) |
158 | if (BN_is_zero(e)) { | 178 | goto err; |
179 | if (BN_mod(e, md, order, ctx) == 0) | ||
180 | goto err; | ||
181 | if (BN_is_zero(e)) | ||
159 | BN_one(e); | 182 | BN_one(e); |
160 | } | ||
161 | k = BN_CTX_get(ctx); | 183 | k = BN_CTX_get(ctx); |
162 | X = BN_CTX_get(ctx); | 184 | X = BN_CTX_get(ctx); |
163 | C = EC_POINT_new(group); | 185 | C = EC_POINT_new(group); |
186 | if (C == NULL) | ||
187 | goto err; | ||
164 | do { | 188 | do { |
165 | do { | 189 | do { |
166 | if (!BN_rand_range(k, order)) { | 190 | if (!BN_rand_range(k, order)) { |
167 | GOSTerr(GOST_F_GOST2001_DO_SIGN, | 191 | GOSTerr(GOST_F_GOST2001_DO_SIGN, |
168 | GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); | 192 | GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); |
169 | ECDSA_SIG_free(newsig); | ||
170 | newsig = NULL; | ||
171 | goto err; | 193 | goto err; |
172 | } | 194 | } |
173 | /* We do not want timing information to leak the length of k, | 195 | /* |
174 | * so we compute G*k using an equivalent scalar of fixed | 196 | * We do not want timing information to leak the length |
175 | * bit-length. */ | 197 | * of k, so we compute G*k using an equivalent scalar |
176 | if (!BN_add(k, k, order)) | 198 | * of fixed bit-length. |
199 | */ | ||
200 | if (BN_add(k, k, order) == 0) | ||
177 | goto err; | 201 | goto err; |
178 | if (BN_num_bits(k) <= BN_num_bits(order)) | 202 | if (BN_num_bits(k) <= BN_num_bits(order)) |
179 | if (!BN_add(k, k, order)) | 203 | if (BN_add(k, k, order) == 0) |
180 | goto err; | 204 | goto err; |
181 | 205 | ||
182 | if (!EC_POINT_mul(group, C, k, NULL, NULL, ctx)) { | 206 | if (EC_POINT_mul(group, C, k, NULL, NULL, ctx) == 0) { |
183 | GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB); | 207 | GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB); |
184 | ECDSA_SIG_free(newsig); | ||
185 | newsig = NULL; | ||
186 | goto err; | 208 | goto err; |
187 | } | 209 | } |
188 | if (!EC_POINT_get_affine_coordinates_GFp | 210 | if (EC_POINT_get_affine_coordinates_GFp(group, C, X, |
189 | (group, C, X, NULL, ctx)) { | 211 | NULL, ctx) == 0) { |
190 | GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB); | 212 | GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB); |
191 | ECDSA_SIG_free(newsig); | ||
192 | newsig = NULL; | ||
193 | goto err; | 213 | goto err; |
194 | } | 214 | } |
195 | BN_nnmod(r, X, order, ctx); | 215 | if (BN_nnmod(r, X, order, ctx) == 0) |
196 | } | 216 | goto err; |
197 | while (BN_is_zero(r)); | 217 | } while (BN_is_zero(r)); |
198 | /* s = (r*priv_key+k*e) mod order */ | 218 | /* s = (r*priv_key+k*e) mod order */ |
199 | if (!tmp) | 219 | if (tmp == NULL) { |
200 | tmp = BN_CTX_get(ctx); | 220 | tmp = BN_CTX_get(ctx); |
201 | BN_mod_mul(tmp, priv_key, r, order, ctx); | 221 | if (tmp == NULL) |
202 | if (!tmp2) | 222 | goto err; |
223 | } | ||
224 | if (BN_mod_mul(tmp, priv_key, r, order, ctx) == 0) | ||
225 | goto err; | ||
226 | if (tmp2 == NULL) { | ||
203 | tmp2 = BN_CTX_get(ctx); | 227 | tmp2 = BN_CTX_get(ctx); |
204 | BN_mod_mul(tmp2, k, e, order, ctx); | 228 | if (tmp2 == NULL) |
205 | BN_mod_add(s, tmp, tmp2, order, ctx); | 229 | goto err; |
206 | } | 230 | } |
207 | while (BN_is_zero(s)); | 231 | if (BN_mod_mul(tmp2, k, e, order, ctx) == 0) |
232 | goto err; | ||
233 | if (BN_mod_add(s, tmp, tmp2, order, ctx) == 0) | ||
234 | goto err; | ||
235 | } while (BN_is_zero(s)); | ||
236 | ok = 1; | ||
208 | 237 | ||
209 | err: | 238 | err: |
210 | BN_CTX_end(ctx); | ||
211 | BN_CTX_free(ctx); | ||
212 | EC_POINT_free(C); | 239 | EC_POINT_free(C); |
213 | BN_free(md); | 240 | if (ctx != NULL) { |
241 | BN_CTX_end(ctx); | ||
242 | BN_CTX_free(ctx); | ||
243 | } | ||
244 | if (ok == 0) { | ||
245 | ECDSA_SIG_free(newsig); | ||
246 | newsig = NULL; | ||
247 | } | ||
214 | return newsig; | 248 | return newsig; |
215 | } | 249 | } |
216 | 250 | ||
217 | int gost2001_do_verify(BIGNUM * md, ECDSA_SIG * sig, GOST_KEY * ec) | 251 | int |
252 | gost2001_do_verify(BIGNUM *md, ECDSA_SIG *sig, GOST_KEY *ec) | ||
218 | { | 253 | { |
219 | BN_CTX *ctx = BN_CTX_new(); | 254 | BN_CTX *ctx = BN_CTX_new(); |
220 | const EC_GROUP *group = GOST_KEY_get0_group(ec); | 255 | const EC_GROUP *group = GOST_KEY_get0_group(ec); |
@@ -225,6 +260,8 @@ int gost2001_do_verify(BIGNUM * md, ECDSA_SIG * sig, GOST_KEY * ec) | |||
225 | const EC_POINT *pub_key = NULL; | 260 | const EC_POINT *pub_key = NULL; |
226 | int ok = 0; | 261 | int ok = 0; |
227 | 262 | ||
263 | if (ctx == NULL) | ||
264 | goto err; | ||
228 | BN_CTX_start(ctx); | 265 | BN_CTX_start(ctx); |
229 | order = BN_CTX_get(ctx); | 266 | order = BN_CTX_get(ctx); |
230 | e = BN_CTX_get(ctx); | 267 | e = BN_CTX_get(ctx); |
@@ -234,88 +271,129 @@ int gost2001_do_verify(BIGNUM * md, ECDSA_SIG * sig, GOST_KEY * ec) | |||
234 | X = BN_CTX_get(ctx); | 271 | X = BN_CTX_get(ctx); |
235 | R = BN_CTX_get(ctx); | 272 | R = BN_CTX_get(ctx); |
236 | v = BN_CTX_get(ctx); | 273 | v = BN_CTX_get(ctx); |
274 | if (v == NULL) | ||
275 | goto err; | ||
237 | 276 | ||
238 | EC_GROUP_get_order(group, order, ctx); | 277 | if (EC_GROUP_get_order(group, order, ctx) == 0) |
278 | goto err; | ||
239 | pub_key = GOST_KEY_get0_public_key(ec); | 279 | pub_key = GOST_KEY_get0_public_key(ec); |
240 | if (BN_is_zero(sig->s) || BN_is_zero(sig->r) || | 280 | if (BN_is_zero(sig->s) || BN_is_zero(sig->r) || |
241 | (BN_cmp(sig->s, order) >= 1) || (BN_cmp(sig->r, order) >= 1)) { | 281 | BN_cmp(sig->s, order) >= 1 || BN_cmp(sig->r, order) >= 1) { |
242 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q); | 282 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, |
283 | GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q); | ||
243 | goto err; | 284 | goto err; |
244 | |||
245 | } | 285 | } |
246 | 286 | ||
247 | BN_mod(e, md, order, ctx); | 287 | if (BN_mod(e, md, order, ctx) == 0) |
288 | goto err; | ||
248 | if (BN_is_zero(e)) | 289 | if (BN_is_zero(e)) |
249 | BN_one(e); | 290 | BN_one(e); |
250 | v = BN_mod_inverse(v, e, order, ctx); | 291 | v = BN_mod_inverse(v, e, order, ctx); |
251 | BN_mod_mul(z1, sig->s, v, order, ctx); | 292 | if (v == NULL) |
252 | BN_sub(tmp, order, sig->r); | 293 | goto err; |
253 | BN_mod_mul(z2, tmp, v, order, ctx); | 294 | if (BN_mod_mul(z1, sig->s, v, order, ctx) == 0) |
295 | goto err; | ||
296 | if (BN_sub(tmp, order, sig->r) == 0) | ||
297 | goto err; | ||
298 | if (BN_mod_mul(z2, tmp, v, order, ctx) == 0) | ||
299 | goto err; | ||
254 | C = EC_POINT_new(group); | 300 | C = EC_POINT_new(group); |
255 | if (!EC_POINT_mul(group, C, z1, pub_key, z2, ctx)) { | 301 | if (C == NULL) |
302 | goto err; | ||
303 | if (EC_POINT_mul(group, C, z1, pub_key, z2, ctx) == 0) { | ||
256 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB); | 304 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB); |
257 | goto err; | 305 | goto err; |
258 | } | 306 | } |
259 | if (!EC_POINT_get_affine_coordinates_GFp(group, C, X, NULL, ctx)) { | 307 | if (EC_POINT_get_affine_coordinates_GFp(group, C, X, NULL, ctx) == 0) { |
260 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB); | 308 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB); |
261 | goto err; | 309 | goto err; |
262 | } | 310 | } |
263 | BN_mod(R, X, order, ctx); | 311 | if (BN_mod(R, X, order, ctx) == 0) |
312 | goto err; | ||
264 | if (BN_cmp(R, sig->r) != 0) { | 313 | if (BN_cmp(R, sig->r) != 0) { |
265 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, GOST_R_SIGNATURE_MISMATCH); | 314 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, GOST_R_SIGNATURE_MISMATCH); |
266 | } else { | 315 | } else { |
267 | ok = 1; | 316 | ok = 1; |
268 | } | 317 | } |
269 | err: | 318 | err: |
270 | EC_POINT_free(C); | 319 | EC_POINT_free(C); |
271 | BN_CTX_end(ctx); | 320 | if (ctx != NULL) { |
272 | BN_CTX_free(ctx); | 321 | BN_CTX_end(ctx); |
322 | BN_CTX_free(ctx); | ||
323 | } | ||
273 | return ok; | 324 | return ok; |
274 | } | 325 | } |
275 | 326 | ||
276 | |||
277 | /* Implementation of CryptoPro VKO 34.10-2001 algorithm */ | 327 | /* Implementation of CryptoPro VKO 34.10-2001 algorithm */ |
278 | void VKO_compute_key(BIGNUM * X, BIGNUM * Y, | 328 | int |
279 | const GOST_KEY * pkey, GOST_KEY * priv_key, | 329 | VKO_compute_key(BIGNUM *X, BIGNUM *Y, const GOST_KEY *pkey, GOST_KEY *priv_key, |
280 | const BIGNUM * ukm) | 330 | const BIGNUM *ukm) |
281 | { | 331 | { |
282 | BIGNUM *p = NULL, *order = NULL; | 332 | BIGNUM *p = NULL, *order = NULL; |
283 | const BIGNUM *key = GOST_KEY_get0_private_key(priv_key); | 333 | const BIGNUM *key = GOST_KEY_get0_private_key(priv_key); |
334 | const EC_GROUP *group = GOST_KEY_get0_group(priv_key); | ||
284 | const EC_POINT *pub_key = GOST_KEY_get0_public_key(pkey); | 335 | const EC_POINT *pub_key = GOST_KEY_get0_public_key(pkey); |
285 | EC_POINT *pnt = EC_POINT_new(GOST_KEY_get0_group(priv_key)); | 336 | EC_POINT *pnt; |
286 | BN_CTX *ctx = BN_CTX_new(); | 337 | BN_CTX *ctx = NULL; |
338 | int ok = 0; | ||
287 | 339 | ||
340 | pnt = EC_POINT_new(group); | ||
341 | if (pnt == NULL) | ||
342 | goto err; | ||
343 | ctx = BN_CTX_new(); | ||
344 | if (ctx == NULL) | ||
345 | goto err; | ||
288 | BN_CTX_start(ctx); | 346 | BN_CTX_start(ctx); |
289 | p = BN_CTX_get(ctx); | 347 | p = BN_CTX_get(ctx); |
290 | order = BN_CTX_get(ctx); | 348 | order = BN_CTX_get(ctx); |
291 | EC_GROUP_get_order(GOST_KEY_get0_group(priv_key), order, ctx); | 349 | if (order == NULL) |
292 | BN_mod_mul(p, key, ukm, order, ctx); | 350 | goto err; |
293 | EC_POINT_mul(GOST_KEY_get0_group(priv_key), pnt, NULL, pub_key, p, ctx); | 351 | if (EC_GROUP_get_order(group, order, ctx) == 0) |
294 | EC_POINT_get_affine_coordinates_GFp(GOST_KEY_get0_group(priv_key), | 352 | goto err; |
295 | pnt, X, Y, ctx); | 353 | if (BN_mod_mul(p, key, ukm, order, ctx) == 0) |
296 | BN_CTX_end(ctx); | 354 | goto err; |
297 | BN_CTX_free(ctx); | 355 | if (EC_POINT_mul(group, pnt, NULL, pub_key, p, ctx) == 0) |
356 | goto err; | ||
357 | if (EC_POINT_get_affine_coordinates_GFp(group, pnt, X, Y, ctx) == 0) | ||
358 | goto err; | ||
359 | ok = 1; | ||
360 | |||
361 | err: | ||
362 | if (ctx != NULL) { | ||
363 | BN_CTX_end(ctx); | ||
364 | BN_CTX_free(ctx); | ||
365 | } | ||
298 | EC_POINT_free(pnt); | 366 | EC_POINT_free(pnt); |
367 | return ok; | ||
299 | } | 368 | } |
300 | 369 | ||
301 | int gost2001_keygen(GOST_KEY * ec) | 370 | int |
371 | gost2001_keygen(GOST_KEY *ec) | ||
302 | { | 372 | { |
303 | BIGNUM *order = BN_new(), *d = BN_new(); | 373 | BIGNUM *order = BN_new(), *d = BN_new(); |
304 | const EC_GROUP *group = GOST_KEY_get0_group(ec); | 374 | const EC_GROUP *group = GOST_KEY_get0_group(ec); |
305 | EC_GROUP_get_order(group, order, NULL); | 375 | int rc = 0; |
376 | |||
377 | if (order == NULL || d == NULL) | ||
378 | goto err; | ||
379 | if (EC_GROUP_get_order(group, order, NULL) == 0) | ||
380 | goto err; | ||
306 | 381 | ||
307 | do { | 382 | do { |
308 | if (!BN_rand_range(d, order)) { | 383 | if (BN_rand_range(d, order) == 0) { |
309 | GOSTerr(GOST_F_GOST2001_KEYGEN, | 384 | GOSTerr(GOST_F_GOST2001_KEYGEN, |
310 | GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); | 385 | GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); |
311 | BN_free(d); | 386 | goto err; |
312 | BN_free(order); | ||
313 | return 0; | ||
314 | } | 387 | } |
315 | } while (BN_is_zero(d)); | 388 | } while (BN_is_zero(d)); |
316 | GOST_KEY_set_private_key(ec, d); | 389 | |
390 | if (GOST_KEY_set_private_key(ec, d) == 0) | ||
391 | goto err; | ||
392 | rc = gost2001_compute_public(ec); | ||
393 | |||
394 | err: | ||
317 | BN_free(d); | 395 | BN_free(d); |
318 | BN_free(order); | 396 | BN_free(order); |
319 | return gost2001_compute_public(ec); | 397 | return rc; |
320 | } | 398 | } |
321 | #endif | 399 | #endif |
diff --git a/src/lib/libcrypto/gost/gostr341001_ameth.c b/src/lib/libcrypto/gost/gostr341001_ameth.c index 710f2aa58c..243a7490fa 100644 --- a/src/lib/libcrypto/gost/gostr341001_ameth.c +++ b/src/lib/libcrypto/gost/gostr341001_ameth.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: gostr341001_ameth.c,v 1.2 2014/11/09 23:06:52 miod Exp $ */ | 1 | /* $OpenBSD: gostr341001_ameth.c,v 1.3 2014/11/13 20:29:55 miod Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> |
4 | * Copyright (c) 2005-2006 Cryptocom LTD | 4 | * Copyright (c) 2005-2006 Cryptocom LTD |
@@ -229,31 +229,34 @@ pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub) | |||
229 | ASN1_OCTET_STRING_free(octet); | 229 | ASN1_OCTET_STRING_free(octet); |
230 | 230 | ||
231 | ret = GOST_KEY_set_public_key_affine_coordinates(pk->pkey.gost, X, Y); | 231 | ret = GOST_KEY_set_public_key_affine_coordinates(pk->pkey.gost, X, Y); |
232 | if (!ret) | 232 | if (ret == 0) |
233 | GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); | 233 | GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); |
234 | 234 | ||
235 | BN_free(X); | 235 | BN_free(X); |
236 | BN_free(Y); | 236 | BN_free(Y); |
237 | 237 | ||
238 | return ret; | 238 | return ret; |
239 | |||
240 | } | 239 | } |
241 | 240 | ||
242 | static int pub_encode_gost01(X509_PUBKEY * pub, const EVP_PKEY * pk) | 241 | static int |
242 | pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk) | ||
243 | { | 243 | { |
244 | ASN1_OBJECT *algobj = NULL; | 244 | ASN1_OBJECT *algobj = NULL; |
245 | ASN1_OCTET_STRING *octet = NULL; | 245 | ASN1_OCTET_STRING *octet = NULL; |
246 | ASN1_STRING *params = NULL; | ||
246 | void *pval = NULL; | 247 | void *pval = NULL; |
247 | unsigned char *buf = NULL, *sptr; | 248 | unsigned char *buf = NULL, *sptr; |
248 | int key_size, ret = 0; | 249 | int key_size, ret = 0; |
249 | const EC_POINT *pub_key; | 250 | const EC_POINT *pub_key; |
250 | BIGNUM *X, *Y; | 251 | BIGNUM *X = NULL, *Y = NULL; |
251 | const GOST_KEY *ec = pk->pkey.gost; | 252 | const GOST_KEY *ec = pk->pkey.gost; |
252 | int ptype = V_ASN1_UNDEF; | 253 | int ptype = V_ASN1_UNDEF; |
253 | 254 | ||
254 | algobj = OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(ec))); | 255 | algobj = OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(ec))); |
255 | if (pk->save_parameters) { | 256 | if (pk->save_parameters) { |
256 | ASN1_STRING *params = encode_gost01_algor_params(pk); | 257 | params = encode_gost01_algor_params(pk); |
258 | if (params == NULL) | ||
259 | return 0; | ||
257 | pval = params; | 260 | pval = params; |
258 | ptype = V_ASN1_SEQUENCE; | 261 | ptype = V_ASN1_SEQUENCE; |
259 | } | 262 | } |
@@ -261,44 +264,43 @@ static int pub_encode_gost01(X509_PUBKEY * pub, const EVP_PKEY * pk) | |||
261 | key_size = GOST_KEY_get_size(ec); | 264 | key_size = GOST_KEY_get_size(ec); |
262 | 265 | ||
263 | pub_key = GOST_KEY_get0_public_key(ec); | 266 | pub_key = GOST_KEY_get0_public_key(ec); |
264 | if (!pub_key) { | 267 | if (pub_key == NULL) { |
265 | GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED); | 268 | GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED); |
266 | return 0; | 269 | goto err; |
267 | } | 270 | } |
268 | 271 | ||
269 | octet = ASN1_OCTET_STRING_new(); | 272 | octet = ASN1_OCTET_STRING_new(); |
270 | if (!octet) { | 273 | if (octet == NULL) { |
271 | GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); | 274 | GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); |
272 | return 0; | 275 | goto err; |
273 | } | 276 | } |
274 | 277 | ||
275 | ret = ASN1_STRING_set(octet, NULL, 2 * key_size); | 278 | ret = ASN1_STRING_set(octet, NULL, 2 * key_size); |
276 | if (!ret) { | 279 | if (ret == 0) { |
277 | GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_INTERNAL_ERROR); | 280 | GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_INTERNAL_ERROR); |
278 | ASN1_BIT_STRING_free(octet); | 281 | goto err; |
279 | return 0; | ||
280 | } | 282 | } |
281 | 283 | ||
282 | sptr = ASN1_STRING_data(octet); | 284 | sptr = ASN1_STRING_data(octet); |
283 | 285 | ||
284 | X = BN_new(); | 286 | X = BN_new(); |
285 | Y = BN_new(); | 287 | Y = BN_new(); |
286 | if (!X || !Y) { | 288 | if (X == NULL || Y == NULL) { |
287 | GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); | 289 | GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); |
288 | ASN1_BIT_STRING_free(octet); | 290 | goto err; |
289 | BN_free(X); | ||
290 | BN_free(Y); | ||
291 | return 0; | ||
292 | } | 291 | } |
293 | 292 | ||
294 | EC_POINT_get_affine_coordinates_GFp(GOST_KEY_get0_group(ec), | 293 | if (EC_POINT_get_affine_coordinates_GFp(GOST_KEY_get0_group(ec), |
295 | pub_key, X, Y, NULL); | 294 | pub_key, X, Y, NULL) == 0) { |
295 | GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_EC_LIB); | ||
296 | goto err; | ||
297 | } | ||
296 | 298 | ||
297 | GOST_bn2le(X, sptr, key_size); | 299 | GOST_bn2le(X, sptr, key_size); |
298 | GOST_bn2le(Y, sptr + key_size, key_size); | 300 | GOST_bn2le(Y, sptr + key_size, key_size); |
299 | 301 | ||
300 | BN_free(X); | ||
301 | BN_free(Y); | 302 | BN_free(Y); |
303 | BN_free(X); | ||
302 | 304 | ||
303 | ret = i2d_ASN1_OCTET_STRING(octet, &buf); | 305 | ret = i2d_ASN1_OCTET_STRING(octet, &buf); |
304 | ASN1_BIT_STRING_free(octet); | 306 | ASN1_BIT_STRING_free(octet); |
@@ -306,48 +308,60 @@ static int pub_encode_gost01(X509_PUBKEY * pub, const EVP_PKEY * pk) | |||
306 | return 0; | 308 | return 0; |
307 | 309 | ||
308 | return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); | 310 | return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); |
311 | |||
312 | err: | ||
313 | BN_free(Y); | ||
314 | BN_free(X); | ||
315 | ASN1_BIT_STRING_free(octet); | ||
316 | ASN1_STRING_free(params); | ||
317 | return 0; | ||
309 | } | 318 | } |
310 | 319 | ||
311 | static int param_print_gost01(BIO * out, const EVP_PKEY * pkey, int indent, | 320 | static int |
312 | ASN1_PCTX * pctx) | 321 | param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) |
313 | { | 322 | { |
314 | int param_nid = EC_GROUP_get_curve_name(GOST_KEY_get0_group(pkey->pkey.gost)); | 323 | int param_nid = |
315 | if (!BIO_indent(out, indent, 128)) | 324 | EC_GROUP_get_curve_name(GOST_KEY_get0_group(pkey->pkey.gost)); |
325 | |||
326 | if (BIO_indent(out, indent, 128) == 0) | ||
316 | return 0; | 327 | return 0; |
317 | BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); | 328 | BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); |
318 | if (!BIO_indent(out, indent, 128)) | 329 | if (BIO_indent(out, indent, 128) == 0) |
319 | return 0; | 330 | return 0; |
320 | BIO_printf(out, "Digest Algorithm: %s\n", OBJ_nid2ln(GOST_KEY_get_digest(pkey->pkey.gost))); | 331 | BIO_printf(out, "Digest Algorithm: %s\n", |
332 | OBJ_nid2ln(GOST_KEY_get_digest(pkey->pkey.gost))); | ||
321 | return 1; | 333 | return 1; |
322 | } | 334 | } |
323 | 335 | ||
324 | static int pub_print_gost01(BIO * out, const EVP_PKEY * pkey, int indent, | 336 | static int |
325 | ASN1_PCTX * pctx) | 337 | pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) |
326 | { | 338 | { |
327 | BN_CTX *ctx = BN_CTX_new(); | 339 | BN_CTX *ctx = BN_CTX_new(); |
328 | BIGNUM *X, *Y; | 340 | BIGNUM *X, *Y; |
329 | const EC_POINT *pubkey; | 341 | const EC_POINT *pubkey; |
330 | const EC_GROUP *group; | 342 | const EC_GROUP *group; |
331 | 343 | ||
332 | if (!ctx) { | 344 | if (ctx == NULL) { |
333 | GOSTerr(GOST_F_PUB_PRINT_GOST01, ERR_R_MALLOC_FAILURE); | 345 | GOSTerr(GOST_F_PUB_PRINT_GOST01, ERR_R_MALLOC_FAILURE); |
334 | return 0; | 346 | return 0; |
335 | } | 347 | } |
336 | BN_CTX_start(ctx); | 348 | BN_CTX_start(ctx); |
337 | X = BN_CTX_get(ctx); | 349 | X = BN_CTX_get(ctx); |
338 | Y = BN_CTX_get(ctx); | 350 | Y = BN_CTX_get(ctx); |
351 | if (X == NULL || Y == NULL) | ||
352 | goto err; | ||
339 | pubkey = GOST_KEY_get0_public_key(pkey->pkey.gost); | 353 | pubkey = GOST_KEY_get0_public_key(pkey->pkey.gost); |
340 | group = GOST_KEY_get0_group(pkey->pkey.gost); | 354 | group = GOST_KEY_get0_group(pkey->pkey.gost); |
341 | if (!EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y, ctx)) { | 355 | if (EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y, |
356 | ctx) == 0) { | ||
342 | GOSTerr(GOST_F_PUB_PRINT_GOST01, ERR_R_EC_LIB); | 357 | GOSTerr(GOST_F_PUB_PRINT_GOST01, ERR_R_EC_LIB); |
343 | BN_CTX_free(ctx); | 358 | goto err; |
344 | return 0; | ||
345 | } | 359 | } |
346 | if (!BIO_indent(out, indent, 128)) | 360 | if (BIO_indent(out, indent, 128) == 0) |
347 | return 0; | 361 | goto err; |
348 | BIO_printf(out, "Public key:\n"); | 362 | BIO_printf(out, "Public key:\n"); |
349 | if (!BIO_indent(out, indent + 3, 128)) | 363 | if (BIO_indent(out, indent + 3, 128) == 0) |
350 | return 0; | 364 | goto err; |
351 | BIO_printf(out, "X:"); | 365 | BIO_printf(out, "X:"); |
352 | BN_print(out, X); | 366 | BN_print(out, X); |
353 | BIO_printf(out, "\n"); | 367 | BIO_printf(out, "\n"); |
@@ -355,22 +369,28 @@ static int pub_print_gost01(BIO * out, const EVP_PKEY * pkey, int indent, | |||
355 | BIO_printf(out, "Y:"); | 369 | BIO_printf(out, "Y:"); |
356 | BN_print(out, Y); | 370 | BN_print(out, Y); |
357 | BIO_printf(out, "\n"); | 371 | BIO_printf(out, "\n"); |
372 | |||
358 | BN_CTX_end(ctx); | 373 | BN_CTX_end(ctx); |
359 | BN_CTX_free(ctx); | 374 | BN_CTX_free(ctx); |
360 | 375 | ||
361 | return param_print_gost01(out, pkey, indent, pctx); | 376 | return param_print_gost01(out, pkey, indent, pctx); |
377 | |||
378 | err: | ||
379 | BN_CTX_end(ctx); | ||
380 | BN_CTX_free(ctx); | ||
381 | return 0; | ||
362 | } | 382 | } |
363 | 383 | ||
364 | static int priv_print_gost01(BIO * out, const EVP_PKEY * pkey, int indent, | 384 | static int |
365 | ASN1_PCTX * pctx) | 385 | priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) |
366 | { | 386 | { |
367 | const BIGNUM *key; | 387 | const BIGNUM *key; |
368 | 388 | ||
369 | if (!BIO_indent(out, indent, 128)) | 389 | if (BIO_indent(out, indent, 128) == 0) |
370 | return 0; | 390 | return 0; |
371 | BIO_printf(out, "Private key: "); | 391 | BIO_printf(out, "Private key: "); |
372 | key = GOST_KEY_get0_private_key(pkey->pkey.gost); | 392 | key = GOST_KEY_get0_private_key(pkey->pkey.gost); |
373 | if (!key) | 393 | if (key == NULL) |
374 | BIO_printf(out, "<undefined)"); | 394 | BIO_printf(out, "<undefined)"); |
375 | else | 395 | else |
376 | BN_print(out, key); | 396 | BN_print(out, key); |
@@ -415,6 +435,7 @@ priv_decode_gost01(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) | |||
415 | 435 | ||
416 | if (s == NULL || s->length != 32) { | 436 | if (s == NULL || s->length != 32) { |
417 | GOSTerr(GOST_F_PRIV_DECODE_GOST01, EVP_R_DECODE_ERROR); | 437 | GOSTerr(GOST_F_PRIV_DECODE_GOST01, EVP_R_DECODE_ERROR); |
438 | ASN1_STRING_free(s); | ||
418 | return 0; | 439 | return 0; |
419 | } | 440 | } |
420 | for (i = 0; i < 32; i++) { | 441 | for (i = 0; i < 32; i++) { |
@@ -424,70 +445,89 @@ priv_decode_gost01(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) | |||
424 | pk_num = BN_bin2bn(rev_buf, 32, NULL); | 445 | pk_num = BN_bin2bn(rev_buf, 32, NULL); |
425 | } else { | 446 | } else { |
426 | priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len); | 447 | priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len); |
427 | if (!priv_key) | 448 | if (priv_key == NULL) |
428 | return 0; | 449 | return 0; |
429 | ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL); | 450 | ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL); |
430 | ASN1_INTEGER_free(priv_key); | 451 | ASN1_INTEGER_free(priv_key); |
431 | if (!ret) { | 452 | if (ret == 0) { |
432 | GOSTerr(GOST_F_PRIV_DECODE_GOST01, EVP_R_DECODE_ERROR); | 453 | GOSTerr(GOST_F_PRIV_DECODE_GOST01, EVP_R_DECODE_ERROR); |
433 | return 0; | 454 | return 0; |
434 | } | 455 | } |
435 | } | 456 | } |
436 | 457 | ||
437 | ec = pk->pkey.gost; | 458 | ec = pk->pkey.gost; |
438 | if (!ec) { | 459 | if (ec == NULL) { |
439 | ec = GOST_KEY_new(); | 460 | ec = GOST_KEY_new(); |
440 | EVP_PKEY_assign_GOST(pk, ec); | 461 | if (ec == NULL) { |
462 | BN_free(pk_num); | ||
463 | return 0; | ||
464 | } | ||
465 | if (EVP_PKEY_assign_GOST(pk, ec) == 0) { | ||
466 | BN_free(pk_num); | ||
467 | GOST_KEY_free(ec); | ||
468 | return 0; | ||
469 | } | ||
441 | } | 470 | } |
442 | if (!GOST_KEY_set_private_key(ec, pk_num)) { | 471 | if (GOST_KEY_set_private_key(ec, pk_num) == 0) { |
443 | BN_free(pk_num); | 472 | BN_free(pk_num); |
444 | return 0; | 473 | return 0; |
445 | } | 474 | } |
446 | if (!EVP_PKEY_missing_parameters(pk)) | 475 | ret = 0; |
447 | gost2001_compute_public(ec); | 476 | if (EVP_PKEY_missing_parameters(pk) == 0) |
477 | ret = gost2001_compute_public(ec) != 0; | ||
448 | BN_free(pk_num); | 478 | BN_free(pk_num); |
449 | 479 | ||
450 | return 1; | 480 | return ret; |
451 | } | 481 | } |
452 | 482 | ||
453 | static int priv_encode_gost01(PKCS8_PRIV_KEY_INFO * p8, const EVP_PKEY * pk) | 483 | static int |
484 | priv_encode_gost01(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) | ||
454 | { | 485 | { |
455 | ASN1_OBJECT *algobj = OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(pk->pkey.gost))); | 486 | ASN1_OBJECT *algobj = |
487 | OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(pk->pkey.gost))); | ||
456 | ASN1_STRING *params = encode_gost01_algor_params(pk); | 488 | ASN1_STRING *params = encode_gost01_algor_params(pk); |
457 | unsigned char *priv_buf = NULL; | 489 | unsigned char *priv_buf = NULL; |
458 | int priv_len; | 490 | int priv_len; |
459 | |||
460 | ASN1_INTEGER *asn1key = NULL; | 491 | ASN1_INTEGER *asn1key = NULL; |
461 | if (!params) { | 492 | |
493 | if (params == NULL) | ||
494 | return 0; | ||
495 | |||
496 | asn1key = BN_to_ASN1_INTEGER(GOST_KEY_get0_private_key(pk->pkey.gost), | ||
497 | NULL); | ||
498 | if (asn1key == NULL) { | ||
499 | ASN1_STRING_free(params); | ||
462 | return 0; | 500 | return 0; |
463 | } | 501 | } |
464 | asn1key = BN_to_ASN1_INTEGER(GOST_KEY_get0_private_key(pk->pkey.gost), NULL); | ||
465 | priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf); | 502 | priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf); |
466 | ASN1_INTEGER_free(asn1key); | 503 | ASN1_INTEGER_free(asn1key); |
467 | return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, | 504 | return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, priv_buf, |
468 | priv_buf, priv_len); | 505 | priv_len); |
469 | } | 506 | } |
470 | 507 | ||
471 | static int param_encode_gost01(const EVP_PKEY * pkey, unsigned char **pder) | 508 | static int |
509 | param_encode_gost01(const EVP_PKEY *pkey, unsigned char **pder) | ||
472 | { | 510 | { |
473 | ASN1_STRING *params = encode_gost01_algor_params(pkey); | 511 | ASN1_STRING *params = encode_gost01_algor_params(pkey); |
474 | int len; | 512 | int len; |
475 | if (!params) | 513 | |
514 | if (params == NULL) | ||
476 | return 0; | 515 | return 0; |
477 | len = params->length; | 516 | len = params->length; |
478 | if (pder) | 517 | if (pder != NULL) |
479 | memcpy(*pder, params->data, params->length); | 518 | memcpy(*pder, params->data, params->length); |
480 | ASN1_STRING_free(params); | 519 | ASN1_STRING_free(params); |
481 | return len; | 520 | return len; |
482 | } | 521 | } |
483 | 522 | ||
484 | static int param_decode_gost01(EVP_PKEY * pkey, const unsigned char **pder, | 523 | static int |
485 | int derlen) | 524 | param_decode_gost01(EVP_PKEY *pkey, const unsigned char **pder, int derlen) |
486 | { | 525 | { |
487 | ASN1_OBJECT *obj = NULL; | 526 | ASN1_OBJECT *obj = NULL; |
488 | int nid; | 527 | int nid; |
489 | GOST_KEY *ec; | 528 | GOST_KEY *ec; |
490 | EC_GROUP *group; | 529 | EC_GROUP *group; |
530 | int ret; | ||
491 | 531 | ||
492 | /* New format */ | 532 | /* New format */ |
493 | if ((V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED) == **pder) | 533 | if ((V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED) == **pder) |
@@ -522,67 +562,85 @@ static int param_decode_gost01(EVP_PKEY * pkey, const unsigned char **pder, | |||
522 | return 0; | 562 | return 0; |
523 | } | 563 | } |
524 | EC_GROUP_free(group); | 564 | EC_GROUP_free(group); |
525 | if (GOST_KEY_set_digest(ec, NID_id_GostR3411_94_CryptoProParamSet) == 0) { | 565 | if (GOST_KEY_set_digest(ec, |
566 | NID_id_GostR3411_94_CryptoProParamSet) == 0) { | ||
526 | GOSTerr(GOST_F_PARAM_DECODE_GOST01, GOST_R_INVALID_DIGEST_TYPE); | 567 | GOSTerr(GOST_F_PARAM_DECODE_GOST01, GOST_R_INVALID_DIGEST_TYPE); |
527 | GOST_KEY_free(ec); | 568 | GOST_KEY_free(ec); |
528 | return 0; | 569 | return 0; |
529 | } | 570 | } |
530 | EVP_PKEY_assign_GOST(pkey, ec); | 571 | ret = EVP_PKEY_assign_GOST(pkey, ec); |
531 | return 1; | 572 | if (ret == 0) |
573 | GOST_KEY_free(ec); | ||
574 | return ret; | ||
532 | } | 575 | } |
533 | 576 | ||
534 | static int param_missing_gost01(const EVP_PKEY * pk) | 577 | static int |
578 | param_missing_gost01(const EVP_PKEY *pk) | ||
535 | { | 579 | { |
536 | const GOST_KEY *ec = pk->pkey.gost; | 580 | const GOST_KEY *ec = pk->pkey.gost; |
537 | if (!ec) | 581 | |
582 | if (ec == NULL) | ||
538 | return 1; | 583 | return 1; |
539 | if (!GOST_KEY_get0_group(ec)) | 584 | if (GOST_KEY_get0_group(ec) == NULL) |
540 | return 1; | 585 | return 1; |
541 | if (GOST_KEY_get_digest(ec) == NID_undef) | 586 | if (GOST_KEY_get_digest(ec) == NID_undef) |
542 | return 1; | 587 | return 1; |
543 | return 0; | 588 | return 0; |
544 | } | 589 | } |
545 | 590 | ||
546 | static int param_copy_gost01(EVP_PKEY * to, const EVP_PKEY * from) | 591 | static int |
592 | param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) | ||
547 | { | 593 | { |
548 | GOST_KEY *eto = to->pkey.gost; | 594 | GOST_KEY *eto = to->pkey.gost; |
549 | const GOST_KEY *efrom = from->pkey.gost; | 595 | const GOST_KEY *efrom = from->pkey.gost; |
596 | int ret = 0; | ||
597 | |||
550 | if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { | 598 | if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { |
551 | GOSTerr(GOST_F_PARAM_COPY_GOST01, | 599 | GOSTerr(GOST_F_PARAM_COPY_GOST01, |
552 | GOST_R_INCOMPATIBLE_ALGORITHMS); | 600 | GOST_R_INCOMPATIBLE_ALGORITHMS); |
553 | return 0; | 601 | return 0; |
554 | } | 602 | } |
555 | if (!efrom) { | 603 | if (efrom == NULL) { |
556 | GOSTerr(GOST_F_PARAM_COPY_GOST01, | 604 | GOSTerr(GOST_F_PARAM_COPY_GOST01, |
557 | GOST_R_KEY_PARAMETERS_MISSING); | 605 | GOST_R_KEY_PARAMETERS_MISSING); |
558 | return 0; | 606 | return 0; |
559 | } | 607 | } |
560 | if (!eto) { | 608 | if (eto) { |
561 | eto = GOST_KEY_new(); | 609 | eto = GOST_KEY_new(); |
562 | EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto); | 610 | if (eto == NULL) { |
611 | GOSTerr(GOST_F_PARAM_COPY_GOST01, | ||
612 | ERR_R_MALLOC_FAILURE); | ||
613 | return 0; | ||
614 | } | ||
615 | if (EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto) == 0) { | ||
616 | GOST_KEY_free(eto); | ||
617 | return 0; | ||
618 | } | ||
563 | } | 619 | } |
564 | GOST_KEY_set_group(eto, GOST_KEY_get0_group(efrom)); | 620 | GOST_KEY_set_group(eto, GOST_KEY_get0_group(efrom)); |
565 | GOST_KEY_set_digest(eto, GOST_KEY_get_digest(efrom)); | 621 | GOST_KEY_set_digest(eto, GOST_KEY_get_digest(efrom)); |
566 | if (GOST_KEY_get0_private_key(eto)) { | 622 | if (GOST_KEY_get0_private_key(eto) != NULL) |
567 | gost2001_compute_public(eto); | 623 | ret = gost2001_compute_public(eto); |
568 | } | 624 | |
569 | return 1; | 625 | return ret; |
570 | } | 626 | } |
571 | 627 | ||
572 | static int param_cmp_gost01(const EVP_PKEY * a, const EVP_PKEY * b) | 628 | static int |
629 | param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) | ||
573 | { | 630 | { |
574 | if (EC_GROUP_get_curve_name(GOST_KEY_get0_group(a->pkey.gost)) != | 631 | if (EC_GROUP_get_curve_name(GOST_KEY_get0_group(a->pkey.gost)) != |
575 | EC_GROUP_get_curve_name(GOST_KEY_get0_group(b->pkey.gost))) { | 632 | EC_GROUP_get_curve_name(GOST_KEY_get0_group(b->pkey.gost))) |
576 | return 0; | 633 | return 0; |
577 | } | 634 | |
578 | if (GOST_KEY_get_digest(a->pkey.gost) != | 635 | if (GOST_KEY_get_digest(a->pkey.gost) != |
579 | GOST_KEY_get_digest(b->pkey.gost)) | 636 | GOST_KEY_get_digest(b->pkey.gost)) |
580 | return 0; | 637 | return 0; |
581 | return 1; | ||
582 | 638 | ||
639 | return 1; | ||
583 | } | 640 | } |
584 | 641 | ||
585 | static int pkey_ctrl_gost01(EVP_PKEY * pkey, int op, long arg1, void *arg2) | 642 | static int |
643 | pkey_ctrl_gost01(EVP_PKEY *pkey, int op, long arg1, void *arg2) | ||
586 | { | 644 | { |
587 | X509_ALGOR *alg1 = NULL, *alg2 = NULL, *alg3 = NULL; | 645 | X509_ALGOR *alg1 = NULL, *alg2 = NULL, *alg3 = NULL; |
588 | int digest = GOST_KEY_get_digest(pkey->pkey.gost); | 646 | int digest = GOST_KEY_get_digest(pkey->pkey.gost); |
diff --git a/src/lib/libcrypto/gost/gostr341001_key.c b/src/lib/libcrypto/gost/gostr341001_key.c index b236dde28a..2405722ddd 100644 --- a/src/lib/libcrypto/gost/gostr341001_key.c +++ b/src/lib/libcrypto/gost/gostr341001_key.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: gostr341001_key.c,v 1.2 2014/11/09 23:06:52 miod Exp $ */ | 1 | /* $OpenBSD: gostr341001_key.c,v 1.3 2014/11/13 20:29:55 miod Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> |
4 | * Copyright (c) 2005-2006 Cryptocom LTD | 4 | * Copyright (c) 2005-2006 Cryptocom LTD |
@@ -176,45 +176,47 @@ err: | |||
176 | return (ok); | 176 | return (ok); |
177 | } | 177 | } |
178 | 178 | ||
179 | int GOST_KEY_set_public_key_affine_coordinates(GOST_KEY * key, BIGNUM * x, BIGNUM * y) | 179 | int |
180 | GOST_KEY_set_public_key_affine_coordinates(GOST_KEY *key, BIGNUM *x, BIGNUM *y) | ||
180 | { | 181 | { |
181 | BN_CTX *ctx = NULL; | 182 | BN_CTX *ctx = NULL; |
182 | BIGNUM *tx, *ty; | 183 | BIGNUM *tx, *ty; |
183 | EC_POINT *point = NULL; | 184 | EC_POINT *point = NULL; |
184 | int ok = 0; | 185 | int ok = 0; |
185 | 186 | ||
186 | if (!key || !key->group || !x || !y) { | 187 | if (key == NULL || key->group == NULL || x == NULL || y == NULL) { |
187 | GOSTerr(GOST_F_GOST_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, | 188 | GOSTerr(GOST_F_GOST_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, |
188 | ERR_R_PASSED_NULL_PARAMETER); | 189 | ERR_R_PASSED_NULL_PARAMETER); |
189 | return 0; | 190 | return 0; |
190 | } | 191 | } |
191 | ctx = BN_CTX_new(); | 192 | ctx = BN_CTX_new(); |
192 | if (!ctx) | 193 | if (ctx == NULL) |
193 | goto err; | 194 | goto err; |
194 | 195 | ||
195 | point = EC_POINT_new(key->group); | 196 | point = EC_POINT_new(key->group); |
196 | 197 | if (point == NULL) | |
197 | if (!point) | ||
198 | goto err; | 198 | goto err; |
199 | 199 | ||
200 | tx = BN_CTX_get(ctx); | 200 | tx = BN_CTX_get(ctx); |
201 | ty = BN_CTX_get(ctx); | 201 | ty = BN_CTX_get(ctx); |
202 | if (!EC_POINT_set_affine_coordinates_GFp(key->group, point, | 202 | if (ty == NULL) |
203 | x, y, ctx)) | 203 | goto err; |
204 | if (EC_POINT_set_affine_coordinates_GFp(key->group, point, x, y, | ||
205 | ctx) == 0) | ||
204 | goto err; | 206 | goto err; |
205 | if (!EC_POINT_get_affine_coordinates_GFp(key->group, point, | 207 | if (EC_POINT_get_affine_coordinates_GFp(key->group, point, tx, ty, |
206 | tx, ty, ctx)) | 208 | ctx) == 0) |
207 | goto err; | 209 | goto err; |
208 | /* | 210 | /* |
209 | * Check if retrieved coordinates match originals: if not values are | 211 | * Check if retrieved coordinates match originals: if not, values are |
210 | * out of range. | 212 | * out of range. |
211 | */ | 213 | */ |
212 | if (BN_cmp(x, tx) || BN_cmp(y, ty)) { | 214 | if (BN_cmp(x, tx) != 0 || BN_cmp(y, ty) != 0) { |
213 | GOSTerr(GOST_F_GOST_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, | 215 | GOSTerr(GOST_F_GOST_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, |
214 | EC_R_COORDINATES_OUT_OF_RANGE); | 216 | EC_R_COORDINATES_OUT_OF_RANGE); |
215 | goto err; | 217 | goto err; |
216 | } | 218 | } |
217 | if (!GOST_KEY_set_public_key(key, point)) | 219 | if (GOST_KEY_set_public_key(key, point) == 0) |
218 | goto err; | 220 | goto err; |
219 | 221 | ||
220 | if (GOST_KEY_check_key(key) == 0) | 222 | if (GOST_KEY_check_key(key) == 0) |
diff --git a/src/lib/libcrypto/gost/gostr341001_pmeth.c b/src/lib/libcrypto/gost/gostr341001_pmeth.c index afcf8f973a..859c0884d6 100644 --- a/src/lib/libcrypto/gost/gostr341001_pmeth.c +++ b/src/lib/libcrypto/gost/gostr341001_pmeth.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: gostr341001_pmeth.c,v 1.5 2014/11/09 23:06:52 miod Exp $ */ | 1 | /* $OpenBSD: gostr341001_pmeth.c,v 1.6 2014/11/13 20:29:55 miod Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> |
4 | * Copyright (c) 2005-2006 Cryptocom LTD | 4 | * Copyright (c) 2005-2006 Cryptocom LTD |
@@ -133,17 +133,19 @@ struct gost_pmeth_data { | |||
133 | int sig_format; | 133 | int sig_format; |
134 | }; | 134 | }; |
135 | 135 | ||
136 | static int pkey_gost01_init(EVP_PKEY_CTX * ctx) | 136 | static int |
137 | pkey_gost01_init(EVP_PKEY_CTX *ctx) | ||
137 | { | 138 | { |
138 | struct gost_pmeth_data *data; | 139 | struct gost_pmeth_data *data; |
139 | EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); | 140 | EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); |
140 | data = malloc(sizeof(struct gost_pmeth_data)); | 141 | |
141 | if (!data) | 142 | data = calloc(1, sizeof(struct gost_pmeth_data)); |
143 | if (data == NULL) | ||
142 | return 0; | 144 | return 0; |
143 | 145 | ||
144 | memset(data, 0, sizeof(struct gost_pmeth_data)); | 146 | if (pkey != NULL && pkey->pkey.gost != NULL) { |
145 | if (pkey && pkey->pkey.gost) { | 147 | data->sign_param_nid = |
146 | data->sign_param_nid = EC_GROUP_get_curve_name(GOST_KEY_get0_group(pkey->pkey.gost)); | 148 | EC_GROUP_get_curve_name(GOST_KEY_get0_group(pkey->pkey.gost)); |
147 | data->digest_nid = GOST_KEY_get_digest(pkey->pkey.gost); | 149 | data->digest_nid = GOST_KEY_get_digest(pkey->pkey.gost); |
148 | } | 150 | } |
149 | EVP_PKEY_CTX_set_data(ctx, data); | 151 | EVP_PKEY_CTX_set_data(ctx, data); |
@@ -151,85 +153,95 @@ static int pkey_gost01_init(EVP_PKEY_CTX * ctx) | |||
151 | } | 153 | } |
152 | 154 | ||
153 | /* Copies contents of gost_pmeth_data structure */ | 155 | /* Copies contents of gost_pmeth_data structure */ |
154 | static int pkey_gost01_copy(EVP_PKEY_CTX * dst, EVP_PKEY_CTX * src) | 156 | static int |
157 | pkey_gost01_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) | ||
155 | { | 158 | { |
156 | struct gost_pmeth_data *dst_data, *src_data; | 159 | struct gost_pmeth_data *dst_data, *src_data; |
157 | if (!pkey_gost01_init(dst)) { | 160 | |
161 | if (pkey_gost01_init(dst) == 0) | ||
158 | return 0; | 162 | return 0; |
159 | } | 163 | |
160 | src_data = EVP_PKEY_CTX_get_data(src); | 164 | src_data = EVP_PKEY_CTX_get_data(src); |
161 | dst_data = EVP_PKEY_CTX_get_data(dst); | 165 | dst_data = EVP_PKEY_CTX_get_data(dst); |
162 | *dst_data = *src_data; | 166 | *dst_data = *src_data; |
163 | if (src_data->shared_ukm) { | 167 | if (src_data->shared_ukm != NULL) |
164 | dst_data->shared_ukm = NULL; | 168 | dst_data->shared_ukm = NULL; |
165 | } | ||
166 | return 1; | 169 | return 1; |
167 | } | 170 | } |
168 | 171 | ||
169 | /* Frees up gost_pmeth_data structure */ | 172 | /* Frees up gost_pmeth_data structure */ |
170 | static void pkey_gost01_cleanup(EVP_PKEY_CTX * ctx) | 173 | static void |
174 | pkey_gost01_cleanup(EVP_PKEY_CTX *ctx) | ||
171 | { | 175 | { |
172 | struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); | 176 | struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); |
177 | |||
173 | free(data->shared_ukm); | 178 | free(data->shared_ukm); |
174 | free(data); | 179 | free(data); |
175 | } | 180 | } |
176 | 181 | ||
177 | static int pkey_gost01_paramgen(EVP_PKEY_CTX * ctx, EVP_PKEY * pkey) | 182 | static int |
183 | pkey_gost01_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) | ||
178 | { | 184 | { |
179 | struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); | 185 | struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); |
180 | EC_GROUP *group; | 186 | EC_GROUP *group; |
181 | GOST_KEY *gost; | 187 | GOST_KEY *gost; |
182 | int ret; | 188 | int ret; |
183 | 189 | ||
184 | if (data->sign_param_nid == NID_undef || data->digest_nid == NID_undef) { | 190 | if (data->sign_param_nid == NID_undef || |
191 | data->digest_nid == NID_undef) { | ||
185 | GOSTerr(GOST_F_PKEY_GOST01_PARAMGEN, GOST_R_NO_PARAMETERS_SET); | 192 | GOSTerr(GOST_F_PKEY_GOST01_PARAMGEN, GOST_R_NO_PARAMETERS_SET); |
186 | return 0; | 193 | return 0; |
187 | } | 194 | } |
188 | 195 | ||
189 | group = EC_GROUP_new_by_curve_name(data->sign_param_nid); | 196 | group = EC_GROUP_new_by_curve_name(data->sign_param_nid); |
190 | if (!group) | 197 | if (group == NULL) |
191 | return 0; | 198 | return 0; |
192 | 199 | ||
193 | EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); | 200 | EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); |
194 | 201 | ||
195 | gost = GOST_KEY_new(); | 202 | gost = GOST_KEY_new(); |
196 | if (!gost) | 203 | if (gost == NULL) |
197 | return 0; | 204 | return 0; |
198 | 205 | ||
199 | if (!GOST_KEY_set_digest(gost, data->digest_nid)) | 206 | if (GOST_KEY_set_digest(gost, data->digest_nid) == 0) |
200 | return 0; | 207 | return 0; |
201 | 208 | ||
202 | ret = GOST_KEY_set_group(gost, group); | 209 | ret = GOST_KEY_set_group(gost, group); |
203 | if (ret) | 210 | if (ret != 0) |
204 | EVP_PKEY_assign_GOST(pkey, gost); | 211 | ret = EVP_PKEY_assign_GOST(pkey, gost); |
205 | else | 212 | if (ret == 0) |
206 | GOST_KEY_free(gost); | 213 | GOST_KEY_free(gost); |
207 | 214 | ||
208 | EC_GROUP_free(group); | 215 | EC_GROUP_free(group); |
209 | return ret; | 216 | return ret; |
210 | } | 217 | } |
211 | 218 | ||
212 | static int pkey_gost01_keygen(EVP_PKEY_CTX * ctx, EVP_PKEY * pkey) | 219 | static int |
220 | pkey_gost01_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) | ||
213 | { | 221 | { |
214 | if (!pkey_gost01_paramgen(ctx, pkey)) | 222 | if (pkey_gost01_paramgen(ctx, pkey) == 0) |
215 | return 0; | 223 | return 0; |
216 | gost2001_keygen(pkey->pkey.gost); | 224 | return gost2001_keygen(pkey->pkey.gost) != 0; |
217 | return 1; | ||
218 | } | 225 | } |
219 | 226 | ||
220 | static int pkey_gost01_sign(EVP_PKEY_CTX * ctx, unsigned char *sig, | 227 | static int |
221 | size_t * siglen, const unsigned char *tbs, | 228 | pkey_gost01_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, |
222 | size_t tbs_len) | 229 | const unsigned char *tbs, size_t tbs_len) |
223 | { | 230 | { |
224 | ECDSA_SIG *unpacked_sig = NULL; | 231 | ECDSA_SIG *unpacked_sig = NULL; |
225 | EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); | 232 | EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); |
226 | struct gost_pmeth_data *pctx = EVP_PKEY_CTX_get_data(ctx); | 233 | struct gost_pmeth_data *pctx = EVP_PKEY_CTX_get_data(ctx); |
227 | BIGNUM *md; | 234 | BIGNUM *md; |
228 | size_t size = GOST_KEY_get_size(pkey->pkey.gost); | 235 | size_t size; |
236 | int ret; | ||
237 | |||
238 | if (pkey == NULL || pkey->pkey.gost == NULL) | ||
239 | return 0; | ||
240 | size = GOST_KEY_get_size(pkey->pkey.gost); | ||
229 | 241 | ||
230 | if (!siglen) | 242 | if (siglen == NULL) |
231 | return 0; | 243 | return 0; |
232 | if (!sig) { | 244 | if (sig == NULL) { |
233 | *siglen = 2 * size; | 245 | *siglen = 2 * size; |
234 | return 1; | 246 | return 1; |
235 | } else if (*siglen < 2 * size) { | 247 | } else if (*siglen < 2 * size) { |
@@ -238,24 +250,32 @@ static int pkey_gost01_sign(EVP_PKEY_CTX * ctx, unsigned char *sig, | |||
238 | } | 250 | } |
239 | OPENSSL_assert(tbs_len == 32 || tbs_len == 64); | 251 | OPENSSL_assert(tbs_len == 32 || tbs_len == 64); |
240 | md = GOST_le2bn(tbs, tbs_len, NULL); | 252 | md = GOST_le2bn(tbs, tbs_len, NULL); |
253 | if (md == NULL) | ||
254 | return 0; | ||
241 | unpacked_sig = gost2001_do_sign(md, pkey->pkey.gost); | 255 | unpacked_sig = gost2001_do_sign(md, pkey->pkey.gost); |
242 | if (!unpacked_sig) { | 256 | BN_free(md); |
257 | if (unpacked_sig == NULL) { | ||
243 | return 0; | 258 | return 0; |
244 | } | 259 | } |
245 | switch (pctx->sig_format) { | 260 | switch (pctx->sig_format) { |
246 | case GOST_SIG_FORMAT_SR_BE: | 261 | case GOST_SIG_FORMAT_SR_BE: |
247 | return pack_signature_cp(unpacked_sig, size, sig, siglen); | 262 | ret = pack_signature_cp(unpacked_sig, size, sig, siglen); |
263 | break; | ||
248 | case GOST_SIG_FORMAT_RS_LE: | 264 | case GOST_SIG_FORMAT_RS_LE: |
249 | return pack_signature_le(unpacked_sig, size, sig, siglen); | 265 | ret = pack_signature_le(unpacked_sig, size, sig, siglen); |
266 | break; | ||
250 | default: | 267 | default: |
251 | ECDSA_SIG_free(unpacked_sig); | 268 | ret = -1; |
252 | return -1; | 269 | break; |
253 | } | 270 | } |
271 | if (ret <= 0) | ||
272 | ECDSA_SIG_free(unpacked_sig); | ||
273 | return ret; | ||
254 | } | 274 | } |
255 | 275 | ||
256 | static int pkey_gost01_verify(EVP_PKEY_CTX * ctx, const unsigned char *sig, | 276 | static int |
257 | size_t siglen, const unsigned char *tbs, | 277 | pkey_gost01_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, |
258 | size_t tbs_len) | 278 | const unsigned char *tbs, size_t tbs_len) |
259 | { | 279 | { |
260 | int ok = 0; | 280 | int ok = 0; |
261 | EVP_PKEY *pub_key = EVP_PKEY_CTX_get0_pkey(ctx); | 281 | EVP_PKEY *pub_key = EVP_PKEY_CTX_get0_pkey(ctx); |
@@ -286,24 +306,33 @@ err: | |||
286 | return ok; | 306 | return ok; |
287 | } | 307 | } |
288 | 308 | ||
289 | static int gost01_VKO_key(EVP_PKEY * pub_key, EVP_PKEY * priv_key, | 309 | static int |
290 | const unsigned char *ukm, unsigned char *key) | 310 | gost01_VKO_key(EVP_PKEY *pub_key, EVP_PKEY *priv_key, const unsigned char *ukm, |
311 | unsigned char *key) | ||
291 | { | 312 | { |
292 | unsigned char hashbuf[128]; | 313 | unsigned char hashbuf[128]; |
293 | int digest_nid; | 314 | int digest_nid; |
294 | int ret; | 315 | int ret = 0; |
295 | BN_CTX *ctx = BN_CTX_new(); | 316 | BN_CTX *ctx = BN_CTX_new(); |
296 | BIGNUM *UKM, *X, *Y; | 317 | BIGNUM *UKM, *X, *Y; |
297 | 318 | ||
319 | if (ctx == NULL) | ||
320 | return 0; | ||
321 | |||
298 | BN_CTX_start(ctx); | 322 | BN_CTX_start(ctx); |
299 | UKM = BN_CTX_get(ctx); | 323 | UKM = BN_CTX_get(ctx); |
300 | X = BN_CTX_get(ctx); | 324 | X = BN_CTX_get(ctx); |
301 | Y = BN_CTX_get(ctx); | 325 | Y = BN_CTX_get(ctx); |
326 | if (Y == NULL) | ||
327 | goto err; | ||
302 | 328 | ||
303 | GOST_le2bn(ukm, 8, UKM); | 329 | GOST_le2bn(ukm, 8, UKM); |
304 | 330 | ||
305 | digest_nid = GOST_KEY_get_digest(priv_key->pkey.gost); | 331 | digest_nid = GOST_KEY_get_digest(priv_key->pkey.gost); |
306 | VKO_compute_key(X, Y, pub_key->pkey.gost, priv_key->pkey.gost, UKM); | 332 | if (VKO_compute_key(X, Y, pub_key->pkey.gost, priv_key->pkey.gost, |
333 | UKM) == 0) | ||
334 | goto err; | ||
335 | |||
307 | switch (digest_nid) { | 336 | switch (digest_nid) { |
308 | case NID_id_GostR3411_94_CryptoProParamSet: | 337 | case NID_id_GostR3411_94_CryptoProParamSet: |
309 | GOST_bn2le(X, hashbuf, 32); | 338 | GOST_bn2le(X, hashbuf, 32); |
@@ -327,14 +356,15 @@ static int gost01_VKO_key(EVP_PKEY * pub_key, EVP_PKEY * priv_key, | |||
327 | ret = -2; | 356 | ret = -2; |
328 | break; | 357 | break; |
329 | } | 358 | } |
359 | err: | ||
330 | BN_CTX_end(ctx); | 360 | BN_CTX_end(ctx); |
331 | BN_CTX_free(ctx); | 361 | BN_CTX_free(ctx); |
332 | return ret; | 362 | return ret; |
333 | } | 363 | } |
334 | 364 | ||
335 | int pkey_gost01_decrypt(EVP_PKEY_CTX * pctx, unsigned char *key, | 365 | int |
336 | size_t * key_len, const unsigned char *in, | 366 | pkey_gost01_decrypt(EVP_PKEY_CTX *pctx, unsigned char *key, size_t *key_len, |
337 | size_t in_len) | 367 | const unsigned char *in, size_t in_len) |
338 | { | 368 | { |
339 | const unsigned char *p = in; | 369 | const unsigned char *p = in; |
340 | EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx); | 370 | EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx); |
@@ -387,26 +417,26 @@ int pkey_gost01_decrypt(EVP_PKEY_CTX * pctx, unsigned char *key, | |||
387 | memcpy(wrappedKey + 8, gkt->key_info->encrypted_key->data, 32); | 417 | memcpy(wrappedKey + 8, gkt->key_info->encrypted_key->data, 32); |
388 | OPENSSL_assert(gkt->key_info->imit->length == 4); | 418 | OPENSSL_assert(gkt->key_info->imit->length == 4); |
389 | memcpy(wrappedKey + 40, gkt->key_info->imit->data, 4); | 419 | memcpy(wrappedKey + 40, gkt->key_info->imit->data, 4); |
390 | gost01_VKO_key(peerkey, priv, wrappedKey, sharedKey); | 420 | if (gost01_VKO_key(peerkey, priv, wrappedKey, sharedKey) <= 0) |
391 | if (!gost_key_unwrap_crypto_pro(nid, sharedKey, wrappedKey, key)) { | 421 | goto err; |
422 | if (gost_key_unwrap_crypto_pro(nid, sharedKey, wrappedKey, key) == 0) { | ||
392 | GOSTerr(GOST_F_PKEY_GOST01_DECRYPT, | 423 | GOSTerr(GOST_F_PKEY_GOST01_DECRYPT, |
393 | GOST_R_ERROR_COMPUTING_SHARED_KEY); | 424 | GOST_R_ERROR_COMPUTING_SHARED_KEY); |
394 | goto err; | 425 | goto err; |
395 | } | 426 | } |
396 | 427 | ||
397 | ret = 1; | 428 | ret = 1; |
398 | err: | 429 | err: |
399 | if (eph_key) | 430 | EVP_PKEY_free(eph_key); |
400 | EVP_PKEY_free(eph_key); | 431 | GOST_KEY_TRANSPORT_free(gkt); |
401 | if (gkt) | ||
402 | GOST_KEY_TRANSPORT_free(gkt); | ||
403 | return ret; | 432 | return ret; |
404 | } | 433 | } |
405 | 434 | ||
406 | int pkey_gost01_derive(EVP_PKEY_CTX * ctx, unsigned char *key, | 435 | int |
407 | size_t * keylen) | 436 | pkey_gost01_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) |
408 | { | 437 | { |
409 | /* Public key of peer in the ctx field peerkey | 438 | /* |
439 | * Public key of peer in the ctx field peerkey | ||
410 | * Our private key in the ctx pkey | 440 | * Our private key in the ctx pkey |
411 | * ukm is in the algorithm specific context data | 441 | * ukm is in the algorithm specific context data |
412 | */ | 442 | */ |
@@ -424,86 +454,98 @@ int pkey_gost01_derive(EVP_PKEY_CTX * ctx, unsigned char *key, | |||
424 | return 32; | 454 | return 32; |
425 | } | 455 | } |
426 | 456 | ||
427 | gost01_VKO_key(peer_key, my_key, data->shared_ukm, key); | 457 | if (gost01_VKO_key(peer_key, my_key, data->shared_ukm, key) <= 0) |
458 | return 0; | ||
459 | |||
428 | *keylen = 32; | 460 | *keylen = 32; |
429 | return 1; | 461 | return 1; |
430 | } | 462 | } |
431 | 463 | ||
432 | int pkey_gost01_encrypt(EVP_PKEY_CTX * pctx, unsigned char *out, | 464 | int |
433 | size_t * out_len, const unsigned char *key, | 465 | pkey_gost01_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len, |
434 | size_t key_len) | 466 | const unsigned char *key, size_t key_len) |
435 | { | 467 | { |
436 | GOST_KEY_TRANSPORT *gkt = NULL; | 468 | GOST_KEY_TRANSPORT *gkt = NULL; |
437 | EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx); | 469 | EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx); |
438 | struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx); | 470 | struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx); |
439 | unsigned char ukm[8], shared_key[32], crypted_key[44]; | 471 | unsigned char ukm[8], shared_key[32], crypted_key[44]; |
440 | int ret = 0; | 472 | int ret = 0; |
441 | int key_is_ephemeral = 1; | 473 | int key_is_ephemeral; |
442 | EVP_PKEY *sec_key = EVP_PKEY_CTX_get0_peerkey(pctx); | 474 | EVP_PKEY *sec_key = EVP_PKEY_CTX_get0_peerkey(pctx); |
443 | int nid = NID_id_Gost28147_89_CryptoPro_A_ParamSet; | 475 | int nid = NID_id_Gost28147_89_CryptoPro_A_ParamSet; |
444 | 476 | ||
445 | if (data->shared_ukm) { | 477 | if (data->shared_ukm != NULL) { |
446 | memcpy(ukm, data->shared_ukm, 8); | 478 | memcpy(ukm, data->shared_ukm, 8); |
447 | } else if (out) { | 479 | } else /* if (out != NULL) */ { |
448 | arc4random_buf(ukm, 8); | 480 | arc4random_buf(ukm, 8); |
449 | } | 481 | } |
450 | /* Check for private key in the peer_key of context */ | 482 | /* Check for private key in the peer_key of context */ |
451 | if (sec_key) { | 483 | if (sec_key) { |
452 | key_is_ephemeral = 0; | 484 | key_is_ephemeral = 0; |
453 | if (!GOST_KEY_get0_private_key(sec_key->pkey.gost)) { | 485 | if (GOST_KEY_get0_private_key(sec_key->pkey.gost) == 0) { |
454 | GOSTerr(GOST_F_PKEY_GOST01_ENCRYPT, | 486 | GOSTerr(GOST_F_PKEY_GOST01_ENCRYPT, |
455 | GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR); | 487 | GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR); |
456 | goto err; | 488 | goto err; |
457 | } | 489 | } |
458 | } else { | 490 | } else { |
459 | key_is_ephemeral = 1; | 491 | key_is_ephemeral = 1; |
460 | if (out) { | 492 | if (out != NULL) { |
493 | GOST_KEY *tmp_key; | ||
494 | |||
461 | sec_key = EVP_PKEY_new(); | 495 | sec_key = EVP_PKEY_new(); |
462 | EVP_PKEY_assign(sec_key, EVP_PKEY_base_id(pubk), | 496 | if (sec_key == NULL) |
463 | GOST_KEY_new()); | 497 | goto err; |
464 | EVP_PKEY_copy_parameters(sec_key, pubk); | 498 | tmp_key = GOST_KEY_new(); |
465 | if (!gost2001_keygen(sec_key->pkey.gost)) { | 499 | if (tmp_key == NULL) |
500 | goto err; | ||
501 | if (EVP_PKEY_assign(sec_key, EVP_PKEY_base_id(pubk), | ||
502 | tmp_key) == 0) { | ||
503 | GOST_KEY_free(tmp_key); | ||
504 | goto err; | ||
505 | } | ||
506 | if (EVP_PKEY_copy_parameters(sec_key, pubk) == 0) | ||
507 | goto err; | ||
508 | if (gost2001_keygen(sec_key->pkey.gost) == 0) { | ||
466 | goto err; | 509 | goto err; |
467 | } | 510 | } |
468 | } | 511 | } |
469 | } | 512 | } |
470 | 513 | ||
471 | if (out) { | 514 | if (out != NULL) { |
472 | gost01_VKO_key(pubk, sec_key, ukm, shared_key); | 515 | if (gost01_VKO_key(pubk, sec_key, ukm, shared_key) <= 0) |
473 | gost_key_wrap_crypto_pro(nid, shared_key, ukm, key, crypted_key); | 516 | goto err; |
517 | gost_key_wrap_crypto_pro(nid, shared_key, ukm, key, | ||
518 | crypted_key); | ||
474 | } | 519 | } |
475 | gkt = GOST_KEY_TRANSPORT_new(); | 520 | gkt = GOST_KEY_TRANSPORT_new(); |
476 | if (!gkt) { | 521 | if (gkt == NULL) |
477 | goto err; | 522 | goto err; |
478 | } | 523 | if (ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, ukm, 8) == 0) |
479 | if (!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, ukm, 8)) { | ||
480 | goto err; | 524 | goto err; |
481 | } | 525 | if (ASN1_OCTET_STRING_set(gkt->key_info->imit, crypted_key + 40, |
482 | if (!ASN1_OCTET_STRING_set(gkt->key_info->imit, crypted_key + 40, 4)) { | 526 | 4) == 0) |
483 | goto err; | 527 | goto err; |
484 | } | 528 | if (ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key, crypted_key + 8, |
485 | if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key, crypted_key + 8, 32)) { | 529 | 32) == 0) |
486 | goto err; | 530 | goto err; |
487 | } | ||
488 | if (key_is_ephemeral) { | 531 | if (key_is_ephemeral) { |
489 | if (!X509_PUBKEY_set | 532 | if (X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key, |
490 | (&gkt->key_agreement_info->ephem_key, | 533 | out != NULL ? sec_key : pubk) == 0) { |
491 | out ? sec_key : pubk)) { | ||
492 | GOSTerr(GOST_F_PKEY_GOST01_ENCRYPT, | 534 | GOSTerr(GOST_F_PKEY_GOST01_ENCRYPT, |
493 | GOST_R_CANNOT_PACK_EPHEMERAL_KEY); | 535 | GOST_R_CANNOT_PACK_EPHEMERAL_KEY); |
494 | goto err; | 536 | goto err; |
495 | } | 537 | } |
496 | } | 538 | } |
497 | ASN1_OBJECT_free(gkt->key_agreement_info->cipher); | 539 | ASN1_OBJECT_free(gkt->key_agreement_info->cipher); |
498 | gkt->key_agreement_info->cipher = OBJ_nid2obj(nid); | 540 | gkt->key_agreement_info->cipher = OBJ_nid2obj(nid); |
499 | if (key_is_ephemeral && sec_key) | 541 | if (key_is_ephemeral) |
500 | EVP_PKEY_free(sec_key); | 542 | EVP_PKEY_free(sec_key); |
501 | if (!key_is_ephemeral) { | 543 | else { |
502 | /* Set control "public key from client certificate used" */ | 544 | /* Set control "public key from client certificate used" */ |
503 | if (EVP_PKEY_CTX_ctrl | 545 | if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, |
504 | (pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0) { | 546 | NULL) <= 0) { |
505 | GOSTerr(GOST_F_PKEY_GOST01_ENCRYPT, | 547 | GOSTerr(GOST_F_PKEY_GOST01_ENCRYPT, |
506 | GOST_R_CTRL_CALL_FAILED); | 548 | GOST_R_CTRL_CALL_FAILED); |
507 | goto err; | 549 | goto err; |
508 | } | 550 | } |
509 | } | 551 | } |
@@ -511,21 +553,26 @@ int pkey_gost01_encrypt(EVP_PKEY_CTX * pctx, unsigned char *out, | |||
511 | ret = 1; | 553 | ret = 1; |
512 | GOST_KEY_TRANSPORT_free(gkt); | 554 | GOST_KEY_TRANSPORT_free(gkt); |
513 | return ret; | 555 | return ret; |
514 | err: | 556 | |
515 | if (key_is_ephemeral && sec_key) | 557 | err: |
558 | if (key_is_ephemeral) | ||
516 | EVP_PKEY_free(sec_key); | 559 | EVP_PKEY_free(sec_key); |
517 | GOST_KEY_TRANSPORT_free(gkt); | 560 | GOST_KEY_TRANSPORT_free(gkt); |
518 | return -1; | 561 | return -1; |
519 | } | 562 | } |
520 | 563 | ||
521 | 564 | ||
522 | static int pkey_gost01_ctrl(EVP_PKEY_CTX * ctx, int type, int p1, void *p2) | 565 | static int |
566 | pkey_gost01_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) | ||
523 | { | 567 | { |
524 | struct gost_pmeth_data *pctx = EVP_PKEY_CTX_get_data(ctx); | 568 | struct gost_pmeth_data *pctx = EVP_PKEY_CTX_get_data(ctx); |
569 | |||
525 | switch (type) { | 570 | switch (type) { |
526 | case EVP_PKEY_CTRL_MD: | 571 | case EVP_PKEY_CTRL_MD: |
527 | if (EVP_MD_type(p2) != GostR3410_get_md_digest(pctx->digest_nid)) { | 572 | if (EVP_MD_type(p2) != |
528 | GOSTerr(GOST_F_PKEY_GOST01_CTRL, GOST_R_INVALID_DIGEST_TYPE); | 573 | GostR3410_get_md_digest(pctx->digest_nid)) { |
574 | GOSTerr(GOST_F_PKEY_GOST01_CTRL, | ||
575 | GOST_R_INVALID_DIGEST_TYPE); | ||
529 | return 0; | 576 | return 0; |
530 | } | 577 | } |
531 | pctx->md = p2; | 578 | pctx->md = p2; |
@@ -546,9 +593,19 @@ static int pkey_gost01_ctrl(EVP_PKEY_CTX * ctx, int type, int p1, void *p2) | |||
546 | return 1; | 593 | return 1; |
547 | 594 | ||
548 | case EVP_PKEY_CTRL_SET_IV: | 595 | case EVP_PKEY_CTRL_SET_IV: |
549 | pctx->shared_ukm = malloc((int)p1); | 596 | { |
550 | memcpy(pctx->shared_ukm, p2, (int)p1); | 597 | char *ukm = malloc(p1); |
598 | |||
599 | if (ukm == NULL) { | ||
600 | GOSTerr(GOST_F_PKEY_GOST01_CTRL, | ||
601 | ERR_R_MALLOC_FAILURE); | ||
602 | return 0; | ||
603 | } | ||
604 | memcpy(ukm, p2, p1); | ||
605 | free(pctx->shared_ukm); | ||
606 | pctx->shared_ukm = ukm; | ||
551 | return 1; | 607 | return 1; |
608 | } | ||
552 | 609 | ||
553 | case EVP_PKEY_CTRL_PEER_KEY: | 610 | case EVP_PKEY_CTRL_PEER_KEY: |
554 | if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */ | 611 | if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */ |
diff --git a/src/lib/libssl/src/crypto/gost/gost89imit_pmeth.c b/src/lib/libssl/src/crypto/gost/gost89imit_pmeth.c index fa79abf0af..00eaf1decc 100644 --- a/src/lib/libssl/src/crypto/gost/gost89imit_pmeth.c +++ b/src/lib/libssl/src/crypto/gost/gost89imit_pmeth.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: gost89imit_pmeth.c,v 1.2 2014/11/09 23:06:52 miod Exp $ */ | 1 | /* $OpenBSD: gost89imit_pmeth.c,v 1.3 2014/11/13 20:29:55 miod Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> |
4 | * Copyright (c) 2005-2006 Cryptocom LTD | 4 | * Copyright (c) 2005-2006 Cryptocom LTD |
@@ -115,20 +115,26 @@ pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) | |||
115 | } | 115 | } |
116 | 116 | ||
117 | keydata = malloc(32); | 117 | keydata = malloc(32); |
118 | if (keydata == NULL) { | ||
119 | GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN, ERR_R_MALLOC_FAILURE); | ||
120 | return 0; | ||
121 | } | ||
118 | memcpy(keydata, data->key, 32); | 122 | memcpy(keydata, data->key, 32); |
119 | EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata); | 123 | EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata); |
120 | 124 | ||
121 | return 1; | 125 | return 1; |
122 | } | 126 | } |
123 | 127 | ||
124 | static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) | 128 | static int |
129 | pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) | ||
125 | { | 130 | { |
126 | struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); | 131 | struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); |
127 | 132 | ||
128 | switch (type) { | 133 | switch (type) { |
129 | case EVP_PKEY_CTRL_MD: | 134 | case EVP_PKEY_CTRL_MD: |
130 | if (EVP_MD_type(p2) != NID_id_Gost28147_89_MAC) { | 135 | if (EVP_MD_type(p2) != NID_id_Gost28147_89_MAC) { |
131 | GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_DIGEST_TYPE); | 136 | GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, |
137 | GOST_R_INVALID_DIGEST_TYPE); | ||
132 | return 0; | 138 | return 0; |
133 | } | 139 | } |
134 | data->md = p2; | 140 | data->md = p2; |
diff --git a/src/lib/libssl/src/crypto/gost/gost_locl.h b/src/lib/libssl/src/crypto/gost/gost_locl.h index 202ba39688..9036f59771 100644 --- a/src/lib/libssl/src/crypto/gost/gost_locl.h +++ b/src/lib/libssl/src/crypto/gost/gost_locl.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: gost_locl.h,v 1.2 2014/11/09 19:27:29 miod Exp $ */ | 1 | /* $OpenBSD: gost_locl.h,v 1.3 2014/11/13 20:29:55 miod Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> |
4 | * Copyright (c) 2005-2006 Cryptocom LTD | 4 | * Copyright (c) 2005-2006 Cryptocom LTD |
@@ -99,7 +99,7 @@ extern int gost2001_compute_public(GOST_KEY *ec); | |||
99 | extern ECDSA_SIG *gost2001_do_sign(BIGNUM *md, GOST_KEY *eckey); | 99 | extern ECDSA_SIG *gost2001_do_sign(BIGNUM *md, GOST_KEY *eckey); |
100 | extern int gost2001_do_verify(BIGNUM *md, ECDSA_SIG *sig, GOST_KEY *ec); | 100 | extern int gost2001_do_verify(BIGNUM *md, ECDSA_SIG *sig, GOST_KEY *ec); |
101 | extern int gost2001_keygen(GOST_KEY *ec); | 101 | extern int gost2001_keygen(GOST_KEY *ec); |
102 | extern void VKO_compute_key(BIGNUM *X, BIGNUM *Y, const GOST_KEY *pkey, | 102 | extern int VKO_compute_key(BIGNUM *X, BIGNUM *Y, const GOST_KEY *pkey, |
103 | GOST_KEY *priv_key, const BIGNUM *ukm); | 103 | GOST_KEY *priv_key, const BIGNUM *ukm); |
104 | extern BIGNUM *GOST_le2bn(const unsigned char *buf, size_t len, BIGNUM *bn); | 104 | extern BIGNUM *GOST_le2bn(const unsigned char *buf, size_t len, BIGNUM *bn); |
105 | extern int GOST_bn2le(BIGNUM *bn, unsigned char *buf, int len); | 105 | extern int GOST_bn2le(BIGNUM *bn, unsigned char *buf, int len); |
diff --git a/src/lib/libssl/src/crypto/gost/gostr341001.c b/src/lib/libssl/src/crypto/gost/gostr341001.c index 3c314765f7..171cf1b80a 100644 --- a/src/lib/libssl/src/crypto/gost/gostr341001.c +++ b/src/lib/libssl/src/crypto/gost/gostr341001.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: gostr341001.c,v 1.1 2014/11/09 19:17:13 miod Exp $ */ | 1 | /* $OpenBSD: gostr341001.c,v 1.2 2014/11/13 20:29:55 miod Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> |
4 | * Copyright (c) 2005-2006 Cryptocom LTD | 4 | * Copyright (c) 2005-2006 Cryptocom LTD |
@@ -59,10 +59,12 @@ | |||
59 | #include "gost_locl.h" | 59 | #include "gost_locl.h" |
60 | 60 | ||
61 | /* Convert little-endian byte array into bignum */ | 61 | /* Convert little-endian byte array into bignum */ |
62 | BIGNUM *GOST_le2bn(const unsigned char * buf, size_t len, BIGNUM * bn) | 62 | BIGNUM * |
63 | GOST_le2bn(const unsigned char *buf, size_t len, BIGNUM *bn) | ||
63 | { | 64 | { |
64 | unsigned char temp[64]; | 65 | unsigned char temp[64]; |
65 | int i; | 66 | int i; |
67 | |||
66 | if (len > 64) | 68 | if (len > 64) |
67 | return NULL; | 69 | return NULL; |
68 | 70 | ||
@@ -73,7 +75,8 @@ BIGNUM *GOST_le2bn(const unsigned char * buf, size_t len, BIGNUM * bn) | |||
73 | return BN_bin2bn(temp, len, bn); | 75 | return BN_bin2bn(temp, len, bn); |
74 | } | 76 | } |
75 | 77 | ||
76 | int GOST_bn2le(BIGNUM * bn, unsigned char * buf, int len) | 78 | int |
79 | GOST_bn2le(BIGNUM *bn, unsigned char *buf, int len) | ||
77 | { | 80 | { |
78 | unsigned char temp[64]; | 81 | unsigned char temp[64]; |
79 | int i, bytes; | 82 | int i, bytes; |
@@ -93,8 +96,8 @@ int GOST_bn2le(BIGNUM * bn, unsigned char * buf, int len) | |||
93 | return 1; | 96 | return 1; |
94 | } | 97 | } |
95 | 98 | ||
96 | 99 | int | |
97 | int gost2001_compute_public(GOST_KEY * ec) | 100 | gost2001_compute_public(GOST_KEY *ec) |
98 | { | 101 | { |
99 | const EC_GROUP *group = GOST_KEY_get0_group(ec); | 102 | const EC_GROUP *group = GOST_KEY_get0_group(ec); |
100 | EC_POINT *pub_key = NULL; | 103 | EC_POINT *pub_key = NULL; |
@@ -102,36 +105,44 @@ int gost2001_compute_public(GOST_KEY * ec) | |||
102 | BN_CTX *ctx = NULL; | 105 | BN_CTX *ctx = NULL; |
103 | int ok = 0; | 106 | int ok = 0; |
104 | 107 | ||
105 | if (!group) { | 108 | if (group == NULL) { |
106 | GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, | 109 | GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, |
107 | GOST_R_KEY_IS_NOT_INITIALIZED); | 110 | GOST_R_KEY_IS_NOT_INITIALIZED); |
108 | return 0; | 111 | return 0; |
109 | } | 112 | } |
110 | ctx = BN_CTX_new(); | 113 | ctx = BN_CTX_new(); |
114 | if (ctx == NULL) { | ||
115 | GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, | ||
116 | ERR_R_MALLOC_FAILURE); | ||
117 | return 0; | ||
118 | } | ||
111 | BN_CTX_start(ctx); | 119 | BN_CTX_start(ctx); |
112 | if (!(priv_key = GOST_KEY_get0_private_key(ec))) { | 120 | if ((priv_key = GOST_KEY_get0_private_key(ec)) == NULL) |
113 | GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); | ||
114 | goto err; | 121 | goto err; |
115 | } | ||
116 | 122 | ||
117 | pub_key = EC_POINT_new(group); | 123 | pub_key = EC_POINT_new(group); |
118 | if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) { | 124 | if (pub_key == NULL) |
119 | GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); | ||
120 | goto err; | 125 | goto err; |
121 | } | 126 | if (EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx) == 0) |
122 | if (!GOST_KEY_set_public_key(ec, pub_key)) { | ||
123 | GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); | ||
124 | goto err; | 127 | goto err; |
125 | } | 128 | if (GOST_KEY_set_public_key(ec, pub_key) == 0) |
126 | ok = 256; | 129 | goto err; |
130 | ok = 1; | ||
131 | |||
132 | if (ok == 0) { | ||
127 | err: | 133 | err: |
128 | BN_CTX_end(ctx); | 134 | GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); |
135 | } | ||
129 | EC_POINT_free(pub_key); | 136 | EC_POINT_free(pub_key); |
130 | BN_CTX_free(ctx); | 137 | if (ctx != NULL) { |
138 | BN_CTX_end(ctx); | ||
139 | BN_CTX_free(ctx); | ||
140 | } | ||
131 | return ok; | 141 | return ok; |
132 | } | 142 | } |
133 | 143 | ||
134 | ECDSA_SIG *gost2001_do_sign(BIGNUM * md, GOST_KEY * eckey) | 144 | ECDSA_SIG * |
145 | gost2001_do_sign(BIGNUM *md, GOST_KEY *eckey) | ||
135 | { | 146 | { |
136 | ECDSA_SIG *newsig = NULL; | 147 | ECDSA_SIG *newsig = NULL; |
137 | BIGNUM *order = NULL; | 148 | BIGNUM *order = NULL; |
@@ -141,9 +152,15 @@ ECDSA_SIG *gost2001_do_sign(BIGNUM * md, GOST_KEY * eckey) | |||
141 | NULL, *e = NULL; | 152 | NULL, *e = NULL; |
142 | EC_POINT *C = NULL; | 153 | EC_POINT *C = NULL; |
143 | BN_CTX *ctx = BN_CTX_new(); | 154 | BN_CTX *ctx = BN_CTX_new(); |
155 | int ok = 0; | ||
156 | |||
157 | if (ctx == NULL) { | ||
158 | GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE); | ||
159 | return NULL; | ||
160 | } | ||
144 | BN_CTX_start(ctx); | 161 | BN_CTX_start(ctx); |
145 | newsig = ECDSA_SIG_new(); | 162 | newsig = ECDSA_SIG_new(); |
146 | if (!newsig) { | 163 | if (newsig == NULL) { |
147 | GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE); | 164 | GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE); |
148 | goto err; | 165 | goto err; |
149 | } | 166 | } |
@@ -151,70 +168,88 @@ ECDSA_SIG *gost2001_do_sign(BIGNUM * md, GOST_KEY * eckey) | |||
151 | r = newsig->r; | 168 | r = newsig->r; |
152 | group = GOST_KEY_get0_group(eckey); | 169 | group = GOST_KEY_get0_group(eckey); |
153 | order = BN_CTX_get(ctx); | 170 | order = BN_CTX_get(ctx); |
154 | EC_GROUP_get_order(group, order, ctx); | 171 | if (order == NULL) |
172 | goto err; | ||
173 | if (EC_GROUP_get_order(group, order, ctx) == 0) | ||
174 | goto err; | ||
155 | priv_key = GOST_KEY_get0_private_key(eckey); | 175 | priv_key = GOST_KEY_get0_private_key(eckey); |
156 | e = BN_CTX_get(ctx); | 176 | e = BN_CTX_get(ctx); |
157 | BN_mod(e, md, order, ctx); | 177 | if (e == NULL) |
158 | if (BN_is_zero(e)) { | 178 | goto err; |
179 | if (BN_mod(e, md, order, ctx) == 0) | ||
180 | goto err; | ||
181 | if (BN_is_zero(e)) | ||
159 | BN_one(e); | 182 | BN_one(e); |
160 | } | ||
161 | k = BN_CTX_get(ctx); | 183 | k = BN_CTX_get(ctx); |
162 | X = BN_CTX_get(ctx); | 184 | X = BN_CTX_get(ctx); |
163 | C = EC_POINT_new(group); | 185 | C = EC_POINT_new(group); |
186 | if (C == NULL) | ||
187 | goto err; | ||
164 | do { | 188 | do { |
165 | do { | 189 | do { |
166 | if (!BN_rand_range(k, order)) { | 190 | if (!BN_rand_range(k, order)) { |
167 | GOSTerr(GOST_F_GOST2001_DO_SIGN, | 191 | GOSTerr(GOST_F_GOST2001_DO_SIGN, |
168 | GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); | 192 | GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); |
169 | ECDSA_SIG_free(newsig); | ||
170 | newsig = NULL; | ||
171 | goto err; | 193 | goto err; |
172 | } | 194 | } |
173 | /* We do not want timing information to leak the length of k, | 195 | /* |
174 | * so we compute G*k using an equivalent scalar of fixed | 196 | * We do not want timing information to leak the length |
175 | * bit-length. */ | 197 | * of k, so we compute G*k using an equivalent scalar |
176 | if (!BN_add(k, k, order)) | 198 | * of fixed bit-length. |
199 | */ | ||
200 | if (BN_add(k, k, order) == 0) | ||
177 | goto err; | 201 | goto err; |
178 | if (BN_num_bits(k) <= BN_num_bits(order)) | 202 | if (BN_num_bits(k) <= BN_num_bits(order)) |
179 | if (!BN_add(k, k, order)) | 203 | if (BN_add(k, k, order) == 0) |
180 | goto err; | 204 | goto err; |
181 | 205 | ||
182 | if (!EC_POINT_mul(group, C, k, NULL, NULL, ctx)) { | 206 | if (EC_POINT_mul(group, C, k, NULL, NULL, ctx) == 0) { |
183 | GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB); | 207 | GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB); |
184 | ECDSA_SIG_free(newsig); | ||
185 | newsig = NULL; | ||
186 | goto err; | 208 | goto err; |
187 | } | 209 | } |
188 | if (!EC_POINT_get_affine_coordinates_GFp | 210 | if (EC_POINT_get_affine_coordinates_GFp(group, C, X, |
189 | (group, C, X, NULL, ctx)) { | 211 | NULL, ctx) == 0) { |
190 | GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB); | 212 | GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB); |
191 | ECDSA_SIG_free(newsig); | ||
192 | newsig = NULL; | ||
193 | goto err; | 213 | goto err; |
194 | } | 214 | } |
195 | BN_nnmod(r, X, order, ctx); | 215 | if (BN_nnmod(r, X, order, ctx) == 0) |
196 | } | 216 | goto err; |
197 | while (BN_is_zero(r)); | 217 | } while (BN_is_zero(r)); |
198 | /* s = (r*priv_key+k*e) mod order */ | 218 | /* s = (r*priv_key+k*e) mod order */ |
199 | if (!tmp) | 219 | if (tmp == NULL) { |
200 | tmp = BN_CTX_get(ctx); | 220 | tmp = BN_CTX_get(ctx); |
201 | BN_mod_mul(tmp, priv_key, r, order, ctx); | 221 | if (tmp == NULL) |
202 | if (!tmp2) | 222 | goto err; |
223 | } | ||
224 | if (BN_mod_mul(tmp, priv_key, r, order, ctx) == 0) | ||
225 | goto err; | ||
226 | if (tmp2 == NULL) { | ||
203 | tmp2 = BN_CTX_get(ctx); | 227 | tmp2 = BN_CTX_get(ctx); |
204 | BN_mod_mul(tmp2, k, e, order, ctx); | 228 | if (tmp2 == NULL) |
205 | BN_mod_add(s, tmp, tmp2, order, ctx); | 229 | goto err; |
206 | } | 230 | } |
207 | while (BN_is_zero(s)); | 231 | if (BN_mod_mul(tmp2, k, e, order, ctx) == 0) |
232 | goto err; | ||
233 | if (BN_mod_add(s, tmp, tmp2, order, ctx) == 0) | ||
234 | goto err; | ||
235 | } while (BN_is_zero(s)); | ||
236 | ok = 1; | ||
208 | 237 | ||
209 | err: | 238 | err: |
210 | BN_CTX_end(ctx); | ||
211 | BN_CTX_free(ctx); | ||
212 | EC_POINT_free(C); | 239 | EC_POINT_free(C); |
213 | BN_free(md); | 240 | if (ctx != NULL) { |
241 | BN_CTX_end(ctx); | ||
242 | BN_CTX_free(ctx); | ||
243 | } | ||
244 | if (ok == 0) { | ||
245 | ECDSA_SIG_free(newsig); | ||
246 | newsig = NULL; | ||
247 | } | ||
214 | return newsig; | 248 | return newsig; |
215 | } | 249 | } |
216 | 250 | ||
217 | int gost2001_do_verify(BIGNUM * md, ECDSA_SIG * sig, GOST_KEY * ec) | 251 | int |
252 | gost2001_do_verify(BIGNUM *md, ECDSA_SIG *sig, GOST_KEY *ec) | ||
218 | { | 253 | { |
219 | BN_CTX *ctx = BN_CTX_new(); | 254 | BN_CTX *ctx = BN_CTX_new(); |
220 | const EC_GROUP *group = GOST_KEY_get0_group(ec); | 255 | const EC_GROUP *group = GOST_KEY_get0_group(ec); |
@@ -225,6 +260,8 @@ int gost2001_do_verify(BIGNUM * md, ECDSA_SIG * sig, GOST_KEY * ec) | |||
225 | const EC_POINT *pub_key = NULL; | 260 | const EC_POINT *pub_key = NULL; |
226 | int ok = 0; | 261 | int ok = 0; |
227 | 262 | ||
263 | if (ctx == NULL) | ||
264 | goto err; | ||
228 | BN_CTX_start(ctx); | 265 | BN_CTX_start(ctx); |
229 | order = BN_CTX_get(ctx); | 266 | order = BN_CTX_get(ctx); |
230 | e = BN_CTX_get(ctx); | 267 | e = BN_CTX_get(ctx); |
@@ -234,88 +271,129 @@ int gost2001_do_verify(BIGNUM * md, ECDSA_SIG * sig, GOST_KEY * ec) | |||
234 | X = BN_CTX_get(ctx); | 271 | X = BN_CTX_get(ctx); |
235 | R = BN_CTX_get(ctx); | 272 | R = BN_CTX_get(ctx); |
236 | v = BN_CTX_get(ctx); | 273 | v = BN_CTX_get(ctx); |
274 | if (v == NULL) | ||
275 | goto err; | ||
237 | 276 | ||
238 | EC_GROUP_get_order(group, order, ctx); | 277 | if (EC_GROUP_get_order(group, order, ctx) == 0) |
278 | goto err; | ||
239 | pub_key = GOST_KEY_get0_public_key(ec); | 279 | pub_key = GOST_KEY_get0_public_key(ec); |
240 | if (BN_is_zero(sig->s) || BN_is_zero(sig->r) || | 280 | if (BN_is_zero(sig->s) || BN_is_zero(sig->r) || |
241 | (BN_cmp(sig->s, order) >= 1) || (BN_cmp(sig->r, order) >= 1)) { | 281 | BN_cmp(sig->s, order) >= 1 || BN_cmp(sig->r, order) >= 1) { |
242 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q); | 282 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, |
283 | GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q); | ||
243 | goto err; | 284 | goto err; |
244 | |||
245 | } | 285 | } |
246 | 286 | ||
247 | BN_mod(e, md, order, ctx); | 287 | if (BN_mod(e, md, order, ctx) == 0) |
288 | goto err; | ||
248 | if (BN_is_zero(e)) | 289 | if (BN_is_zero(e)) |
249 | BN_one(e); | 290 | BN_one(e); |
250 | v = BN_mod_inverse(v, e, order, ctx); | 291 | v = BN_mod_inverse(v, e, order, ctx); |
251 | BN_mod_mul(z1, sig->s, v, order, ctx); | 292 | if (v == NULL) |
252 | BN_sub(tmp, order, sig->r); | 293 | goto err; |
253 | BN_mod_mul(z2, tmp, v, order, ctx); | 294 | if (BN_mod_mul(z1, sig->s, v, order, ctx) == 0) |
295 | goto err; | ||
296 | if (BN_sub(tmp, order, sig->r) == 0) | ||
297 | goto err; | ||
298 | if (BN_mod_mul(z2, tmp, v, order, ctx) == 0) | ||
299 | goto err; | ||
254 | C = EC_POINT_new(group); | 300 | C = EC_POINT_new(group); |
255 | if (!EC_POINT_mul(group, C, z1, pub_key, z2, ctx)) { | 301 | if (C == NULL) |
302 | goto err; | ||
303 | if (EC_POINT_mul(group, C, z1, pub_key, z2, ctx) == 0) { | ||
256 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB); | 304 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB); |
257 | goto err; | 305 | goto err; |
258 | } | 306 | } |
259 | if (!EC_POINT_get_affine_coordinates_GFp(group, C, X, NULL, ctx)) { | 307 | if (EC_POINT_get_affine_coordinates_GFp(group, C, X, NULL, ctx) == 0) { |
260 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB); | 308 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB); |
261 | goto err; | 309 | goto err; |
262 | } | 310 | } |
263 | BN_mod(R, X, order, ctx); | 311 | if (BN_mod(R, X, order, ctx) == 0) |
312 | goto err; | ||
264 | if (BN_cmp(R, sig->r) != 0) { | 313 | if (BN_cmp(R, sig->r) != 0) { |
265 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, GOST_R_SIGNATURE_MISMATCH); | 314 | GOSTerr(GOST_F_GOST2001_DO_VERIFY, GOST_R_SIGNATURE_MISMATCH); |
266 | } else { | 315 | } else { |
267 | ok = 1; | 316 | ok = 1; |
268 | } | 317 | } |
269 | err: | 318 | err: |
270 | EC_POINT_free(C); | 319 | EC_POINT_free(C); |
271 | BN_CTX_end(ctx); | 320 | if (ctx != NULL) { |
272 | BN_CTX_free(ctx); | 321 | BN_CTX_end(ctx); |
322 | BN_CTX_free(ctx); | ||
323 | } | ||
273 | return ok; | 324 | return ok; |
274 | } | 325 | } |
275 | 326 | ||
276 | |||
277 | /* Implementation of CryptoPro VKO 34.10-2001 algorithm */ | 327 | /* Implementation of CryptoPro VKO 34.10-2001 algorithm */ |
278 | void VKO_compute_key(BIGNUM * X, BIGNUM * Y, | 328 | int |
279 | const GOST_KEY * pkey, GOST_KEY * priv_key, | 329 | VKO_compute_key(BIGNUM *X, BIGNUM *Y, const GOST_KEY *pkey, GOST_KEY *priv_key, |
280 | const BIGNUM * ukm) | 330 | const BIGNUM *ukm) |
281 | { | 331 | { |
282 | BIGNUM *p = NULL, *order = NULL; | 332 | BIGNUM *p = NULL, *order = NULL; |
283 | const BIGNUM *key = GOST_KEY_get0_private_key(priv_key); | 333 | const BIGNUM *key = GOST_KEY_get0_private_key(priv_key); |
334 | const EC_GROUP *group = GOST_KEY_get0_group(priv_key); | ||
284 | const EC_POINT *pub_key = GOST_KEY_get0_public_key(pkey); | 335 | const EC_POINT *pub_key = GOST_KEY_get0_public_key(pkey); |
285 | EC_POINT *pnt = EC_POINT_new(GOST_KEY_get0_group(priv_key)); | 336 | EC_POINT *pnt; |
286 | BN_CTX *ctx = BN_CTX_new(); | 337 | BN_CTX *ctx = NULL; |
338 | int ok = 0; | ||
287 | 339 | ||
340 | pnt = EC_POINT_new(group); | ||
341 | if (pnt == NULL) | ||
342 | goto err; | ||
343 | ctx = BN_CTX_new(); | ||
344 | if (ctx == NULL) | ||
345 | goto err; | ||
288 | BN_CTX_start(ctx); | 346 | BN_CTX_start(ctx); |
289 | p = BN_CTX_get(ctx); | 347 | p = BN_CTX_get(ctx); |
290 | order = BN_CTX_get(ctx); | 348 | order = BN_CTX_get(ctx); |
291 | EC_GROUP_get_order(GOST_KEY_get0_group(priv_key), order, ctx); | 349 | if (order == NULL) |
292 | BN_mod_mul(p, key, ukm, order, ctx); | 350 | goto err; |
293 | EC_POINT_mul(GOST_KEY_get0_group(priv_key), pnt, NULL, pub_key, p, ctx); | 351 | if (EC_GROUP_get_order(group, order, ctx) == 0) |
294 | EC_POINT_get_affine_coordinates_GFp(GOST_KEY_get0_group(priv_key), | 352 | goto err; |
295 | pnt, X, Y, ctx); | 353 | if (BN_mod_mul(p, key, ukm, order, ctx) == 0) |
296 | BN_CTX_end(ctx); | 354 | goto err; |
297 | BN_CTX_free(ctx); | 355 | if (EC_POINT_mul(group, pnt, NULL, pub_key, p, ctx) == 0) |
356 | goto err; | ||
357 | if (EC_POINT_get_affine_coordinates_GFp(group, pnt, X, Y, ctx) == 0) | ||
358 | goto err; | ||
359 | ok = 1; | ||
360 | |||
361 | err: | ||
362 | if (ctx != NULL) { | ||
363 | BN_CTX_end(ctx); | ||
364 | BN_CTX_free(ctx); | ||
365 | } | ||
298 | EC_POINT_free(pnt); | 366 | EC_POINT_free(pnt); |
367 | return ok; | ||
299 | } | 368 | } |
300 | 369 | ||
301 | int gost2001_keygen(GOST_KEY * ec) | 370 | int |
371 | gost2001_keygen(GOST_KEY *ec) | ||
302 | { | 372 | { |
303 | BIGNUM *order = BN_new(), *d = BN_new(); | 373 | BIGNUM *order = BN_new(), *d = BN_new(); |
304 | const EC_GROUP *group = GOST_KEY_get0_group(ec); | 374 | const EC_GROUP *group = GOST_KEY_get0_group(ec); |
305 | EC_GROUP_get_order(group, order, NULL); | 375 | int rc = 0; |
376 | |||
377 | if (order == NULL || d == NULL) | ||
378 | goto err; | ||
379 | if (EC_GROUP_get_order(group, order, NULL) == 0) | ||
380 | goto err; | ||
306 | 381 | ||
307 | do { | 382 | do { |
308 | if (!BN_rand_range(d, order)) { | 383 | if (BN_rand_range(d, order) == 0) { |
309 | GOSTerr(GOST_F_GOST2001_KEYGEN, | 384 | GOSTerr(GOST_F_GOST2001_KEYGEN, |
310 | GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); | 385 | GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); |
311 | BN_free(d); | 386 | goto err; |
312 | BN_free(order); | ||
313 | return 0; | ||
314 | } | 387 | } |
315 | } while (BN_is_zero(d)); | 388 | } while (BN_is_zero(d)); |
316 | GOST_KEY_set_private_key(ec, d); | 389 | |
390 | if (GOST_KEY_set_private_key(ec, d) == 0) | ||
391 | goto err; | ||
392 | rc = gost2001_compute_public(ec); | ||
393 | |||
394 | err: | ||
317 | BN_free(d); | 395 | BN_free(d); |
318 | BN_free(order); | 396 | BN_free(order); |
319 | return gost2001_compute_public(ec); | 397 | return rc; |
320 | } | 398 | } |
321 | #endif | 399 | #endif |
diff --git a/src/lib/libssl/src/crypto/gost/gostr341001_ameth.c b/src/lib/libssl/src/crypto/gost/gostr341001_ameth.c index 710f2aa58c..243a7490fa 100644 --- a/src/lib/libssl/src/crypto/gost/gostr341001_ameth.c +++ b/src/lib/libssl/src/crypto/gost/gostr341001_ameth.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: gostr341001_ameth.c,v 1.2 2014/11/09 23:06:52 miod Exp $ */ | 1 | /* $OpenBSD: gostr341001_ameth.c,v 1.3 2014/11/13 20:29:55 miod Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> |
4 | * Copyright (c) 2005-2006 Cryptocom LTD | 4 | * Copyright (c) 2005-2006 Cryptocom LTD |
@@ -229,31 +229,34 @@ pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub) | |||
229 | ASN1_OCTET_STRING_free(octet); | 229 | ASN1_OCTET_STRING_free(octet); |
230 | 230 | ||
231 | ret = GOST_KEY_set_public_key_affine_coordinates(pk->pkey.gost, X, Y); | 231 | ret = GOST_KEY_set_public_key_affine_coordinates(pk->pkey.gost, X, Y); |
232 | if (!ret) | 232 | if (ret == 0) |
233 | GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); | 233 | GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); |
234 | 234 | ||
235 | BN_free(X); | 235 | BN_free(X); |
236 | BN_free(Y); | 236 | BN_free(Y); |
237 | 237 | ||
238 | return ret; | 238 | return ret; |
239 | |||
240 | } | 239 | } |
241 | 240 | ||
242 | static int pub_encode_gost01(X509_PUBKEY * pub, const EVP_PKEY * pk) | 241 | static int |
242 | pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk) | ||
243 | { | 243 | { |
244 | ASN1_OBJECT *algobj = NULL; | 244 | ASN1_OBJECT *algobj = NULL; |
245 | ASN1_OCTET_STRING *octet = NULL; | 245 | ASN1_OCTET_STRING *octet = NULL; |
246 | ASN1_STRING *params = NULL; | ||
246 | void *pval = NULL; | 247 | void *pval = NULL; |
247 | unsigned char *buf = NULL, *sptr; | 248 | unsigned char *buf = NULL, *sptr; |
248 | int key_size, ret = 0; | 249 | int key_size, ret = 0; |
249 | const EC_POINT *pub_key; | 250 | const EC_POINT *pub_key; |
250 | BIGNUM *X, *Y; | 251 | BIGNUM *X = NULL, *Y = NULL; |
251 | const GOST_KEY *ec = pk->pkey.gost; | 252 | const GOST_KEY *ec = pk->pkey.gost; |
252 | int ptype = V_ASN1_UNDEF; | 253 | int ptype = V_ASN1_UNDEF; |
253 | 254 | ||
254 | algobj = OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(ec))); | 255 | algobj = OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(ec))); |
255 | if (pk->save_parameters) { | 256 | if (pk->save_parameters) { |
256 | ASN1_STRING *params = encode_gost01_algor_params(pk); | 257 | params = encode_gost01_algor_params(pk); |
258 | if (params == NULL) | ||
259 | return 0; | ||
257 | pval = params; | 260 | pval = params; |
258 | ptype = V_ASN1_SEQUENCE; | 261 | ptype = V_ASN1_SEQUENCE; |
259 | } | 262 | } |
@@ -261,44 +264,43 @@ static int pub_encode_gost01(X509_PUBKEY * pub, const EVP_PKEY * pk) | |||
261 | key_size = GOST_KEY_get_size(ec); | 264 | key_size = GOST_KEY_get_size(ec); |
262 | 265 | ||
263 | pub_key = GOST_KEY_get0_public_key(ec); | 266 | pub_key = GOST_KEY_get0_public_key(ec); |
264 | if (!pub_key) { | 267 | if (pub_key == NULL) { |
265 | GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED); | 268 | GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED); |
266 | return 0; | 269 | goto err; |
267 | } | 270 | } |
268 | 271 | ||
269 | octet = ASN1_OCTET_STRING_new(); | 272 | octet = ASN1_OCTET_STRING_new(); |
270 | if (!octet) { | 273 | if (octet == NULL) { |
271 | GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); | 274 | GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); |
272 | return 0; | 275 | goto err; |
273 | } | 276 | } |
274 | 277 | ||
275 | ret = ASN1_STRING_set(octet, NULL, 2 * key_size); | 278 | ret = ASN1_STRING_set(octet, NULL, 2 * key_size); |
276 | if (!ret) { | 279 | if (ret == 0) { |
277 | GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_INTERNAL_ERROR); | 280 | GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_INTERNAL_ERROR); |
278 | ASN1_BIT_STRING_free(octet); | 281 | goto err; |
279 | return 0; | ||
280 | } | 282 | } |
281 | 283 | ||
282 | sptr = ASN1_STRING_data(octet); | 284 | sptr = ASN1_STRING_data(octet); |
283 | 285 | ||
284 | X = BN_new(); | 286 | X = BN_new(); |
285 | Y = BN_new(); | 287 | Y = BN_new(); |
286 | if (!X || !Y) { | 288 | if (X == NULL || Y == NULL) { |
287 | GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); | 289 | GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); |
288 | ASN1_BIT_STRING_free(octet); | 290 | goto err; |
289 | BN_free(X); | ||
290 | BN_free(Y); | ||
291 | return 0; | ||
292 | } | 291 | } |
293 | 292 | ||
294 | EC_POINT_get_affine_coordinates_GFp(GOST_KEY_get0_group(ec), | 293 | if (EC_POINT_get_affine_coordinates_GFp(GOST_KEY_get0_group(ec), |
295 | pub_key, X, Y, NULL); | 294 | pub_key, X, Y, NULL) == 0) { |
295 | GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_EC_LIB); | ||
296 | goto err; | ||
297 | } | ||
296 | 298 | ||
297 | GOST_bn2le(X, sptr, key_size); | 299 | GOST_bn2le(X, sptr, key_size); |
298 | GOST_bn2le(Y, sptr + key_size, key_size); | 300 | GOST_bn2le(Y, sptr + key_size, key_size); |
299 | 301 | ||
300 | BN_free(X); | ||
301 | BN_free(Y); | 302 | BN_free(Y); |
303 | BN_free(X); | ||
302 | 304 | ||
303 | ret = i2d_ASN1_OCTET_STRING(octet, &buf); | 305 | ret = i2d_ASN1_OCTET_STRING(octet, &buf); |
304 | ASN1_BIT_STRING_free(octet); | 306 | ASN1_BIT_STRING_free(octet); |
@@ -306,48 +308,60 @@ static int pub_encode_gost01(X509_PUBKEY * pub, const EVP_PKEY * pk) | |||
306 | return 0; | 308 | return 0; |
307 | 309 | ||
308 | return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); | 310 | return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); |
311 | |||
312 | err: | ||
313 | BN_free(Y); | ||
314 | BN_free(X); | ||
315 | ASN1_BIT_STRING_free(octet); | ||
316 | ASN1_STRING_free(params); | ||
317 | return 0; | ||
309 | } | 318 | } |
310 | 319 | ||
311 | static int param_print_gost01(BIO * out, const EVP_PKEY * pkey, int indent, | 320 | static int |
312 | ASN1_PCTX * pctx) | 321 | param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) |
313 | { | 322 | { |
314 | int param_nid = EC_GROUP_get_curve_name(GOST_KEY_get0_group(pkey->pkey.gost)); | 323 | int param_nid = |
315 | if (!BIO_indent(out, indent, 128)) | 324 | EC_GROUP_get_curve_name(GOST_KEY_get0_group(pkey->pkey.gost)); |
325 | |||
326 | if (BIO_indent(out, indent, 128) == 0) | ||
316 | return 0; | 327 | return 0; |
317 | BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); | 328 | BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); |
318 | if (!BIO_indent(out, indent, 128)) | 329 | if (BIO_indent(out, indent, 128) == 0) |
319 | return 0; | 330 | return 0; |
320 | BIO_printf(out, "Digest Algorithm: %s\n", OBJ_nid2ln(GOST_KEY_get_digest(pkey->pkey.gost))); | 331 | BIO_printf(out, "Digest Algorithm: %s\n", |
332 | OBJ_nid2ln(GOST_KEY_get_digest(pkey->pkey.gost))); | ||
321 | return 1; | 333 | return 1; |
322 | } | 334 | } |
323 | 335 | ||
324 | static int pub_print_gost01(BIO * out, const EVP_PKEY * pkey, int indent, | 336 | static int |
325 | ASN1_PCTX * pctx) | 337 | pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) |
326 | { | 338 | { |
327 | BN_CTX *ctx = BN_CTX_new(); | 339 | BN_CTX *ctx = BN_CTX_new(); |
328 | BIGNUM *X, *Y; | 340 | BIGNUM *X, *Y; |
329 | const EC_POINT *pubkey; | 341 | const EC_POINT *pubkey; |
330 | const EC_GROUP *group; | 342 | const EC_GROUP *group; |
331 | 343 | ||
332 | if (!ctx) { | 344 | if (ctx == NULL) { |
333 | GOSTerr(GOST_F_PUB_PRINT_GOST01, ERR_R_MALLOC_FAILURE); | 345 | GOSTerr(GOST_F_PUB_PRINT_GOST01, ERR_R_MALLOC_FAILURE); |
334 | return 0; | 346 | return 0; |
335 | } | 347 | } |
336 | BN_CTX_start(ctx); | 348 | BN_CTX_start(ctx); |
337 | X = BN_CTX_get(ctx); | 349 | X = BN_CTX_get(ctx); |
338 | Y = BN_CTX_get(ctx); | 350 | Y = BN_CTX_get(ctx); |
351 | if (X == NULL || Y == NULL) | ||
352 | goto err; | ||
339 | pubkey = GOST_KEY_get0_public_key(pkey->pkey.gost); | 353 | pubkey = GOST_KEY_get0_public_key(pkey->pkey.gost); |
340 | group = GOST_KEY_get0_group(pkey->pkey.gost); | 354 | group = GOST_KEY_get0_group(pkey->pkey.gost); |
341 | if (!EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y, ctx)) { | 355 | if (EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y, |
356 | ctx) == 0) { | ||
342 | GOSTerr(GOST_F_PUB_PRINT_GOST01, ERR_R_EC_LIB); | 357 | GOSTerr(GOST_F_PUB_PRINT_GOST01, ERR_R_EC_LIB); |
343 | BN_CTX_free(ctx); | 358 | goto err; |
344 | return 0; | ||
345 | } | 359 | } |
346 | if (!BIO_indent(out, indent, 128)) | 360 | if (BIO_indent(out, indent, 128) == 0) |
347 | return 0; | 361 | goto err; |
348 | BIO_printf(out, "Public key:\n"); | 362 | BIO_printf(out, "Public key:\n"); |
349 | if (!BIO_indent(out, indent + 3, 128)) | 363 | if (BIO_indent(out, indent + 3, 128) == 0) |
350 | return 0; | 364 | goto err; |
351 | BIO_printf(out, "X:"); | 365 | BIO_printf(out, "X:"); |
352 | BN_print(out, X); | 366 | BN_print(out, X); |
353 | BIO_printf(out, "\n"); | 367 | BIO_printf(out, "\n"); |
@@ -355,22 +369,28 @@ static int pub_print_gost01(BIO * out, const EVP_PKEY * pkey, int indent, | |||
355 | BIO_printf(out, "Y:"); | 369 | BIO_printf(out, "Y:"); |
356 | BN_print(out, Y); | 370 | BN_print(out, Y); |
357 | BIO_printf(out, "\n"); | 371 | BIO_printf(out, "\n"); |
372 | |||
358 | BN_CTX_end(ctx); | 373 | BN_CTX_end(ctx); |
359 | BN_CTX_free(ctx); | 374 | BN_CTX_free(ctx); |
360 | 375 | ||
361 | return param_print_gost01(out, pkey, indent, pctx); | 376 | return param_print_gost01(out, pkey, indent, pctx); |
377 | |||
378 | err: | ||
379 | BN_CTX_end(ctx); | ||
380 | BN_CTX_free(ctx); | ||
381 | return 0; | ||
362 | } | 382 | } |
363 | 383 | ||
364 | static int priv_print_gost01(BIO * out, const EVP_PKEY * pkey, int indent, | 384 | static int |
365 | ASN1_PCTX * pctx) | 385 | priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) |
366 | { | 386 | { |
367 | const BIGNUM *key; | 387 | const BIGNUM *key; |
368 | 388 | ||
369 | if (!BIO_indent(out, indent, 128)) | 389 | if (BIO_indent(out, indent, 128) == 0) |
370 | return 0; | 390 | return 0; |
371 | BIO_printf(out, "Private key: "); | 391 | BIO_printf(out, "Private key: "); |
372 | key = GOST_KEY_get0_private_key(pkey->pkey.gost); | 392 | key = GOST_KEY_get0_private_key(pkey->pkey.gost); |
373 | if (!key) | 393 | if (key == NULL) |
374 | BIO_printf(out, "<undefined)"); | 394 | BIO_printf(out, "<undefined)"); |
375 | else | 395 | else |
376 | BN_print(out, key); | 396 | BN_print(out, key); |
@@ -415,6 +435,7 @@ priv_decode_gost01(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) | |||
415 | 435 | ||
416 | if (s == NULL || s->length != 32) { | 436 | if (s == NULL || s->length != 32) { |
417 | GOSTerr(GOST_F_PRIV_DECODE_GOST01, EVP_R_DECODE_ERROR); | 437 | GOSTerr(GOST_F_PRIV_DECODE_GOST01, EVP_R_DECODE_ERROR); |
438 | ASN1_STRING_free(s); | ||
418 | return 0; | 439 | return 0; |
419 | } | 440 | } |
420 | for (i = 0; i < 32; i++) { | 441 | for (i = 0; i < 32; i++) { |
@@ -424,70 +445,89 @@ priv_decode_gost01(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) | |||
424 | pk_num = BN_bin2bn(rev_buf, 32, NULL); | 445 | pk_num = BN_bin2bn(rev_buf, 32, NULL); |
425 | } else { | 446 | } else { |
426 | priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len); | 447 | priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len); |
427 | if (!priv_key) | 448 | if (priv_key == NULL) |
428 | return 0; | 449 | return 0; |
429 | ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL); | 450 | ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL); |
430 | ASN1_INTEGER_free(priv_key); | 451 | ASN1_INTEGER_free(priv_key); |
431 | if (!ret) { | 452 | if (ret == 0) { |
432 | GOSTerr(GOST_F_PRIV_DECODE_GOST01, EVP_R_DECODE_ERROR); | 453 | GOSTerr(GOST_F_PRIV_DECODE_GOST01, EVP_R_DECODE_ERROR); |
433 | return 0; | 454 | return 0; |
434 | } | 455 | } |
435 | } | 456 | } |
436 | 457 | ||
437 | ec = pk->pkey.gost; | 458 | ec = pk->pkey.gost; |
438 | if (!ec) { | 459 | if (ec == NULL) { |
439 | ec = GOST_KEY_new(); | 460 | ec = GOST_KEY_new(); |
440 | EVP_PKEY_assign_GOST(pk, ec); | 461 | if (ec == NULL) { |
462 | BN_free(pk_num); | ||
463 | return 0; | ||
464 | } | ||
465 | if (EVP_PKEY_assign_GOST(pk, ec) == 0) { | ||
466 | BN_free(pk_num); | ||
467 | GOST_KEY_free(ec); | ||
468 | return 0; | ||
469 | } | ||
441 | } | 470 | } |
442 | if (!GOST_KEY_set_private_key(ec, pk_num)) { | 471 | if (GOST_KEY_set_private_key(ec, pk_num) == 0) { |
443 | BN_free(pk_num); | 472 | BN_free(pk_num); |
444 | return 0; | 473 | return 0; |
445 | } | 474 | } |
446 | if (!EVP_PKEY_missing_parameters(pk)) | 475 | ret = 0; |
447 | gost2001_compute_public(ec); | 476 | if (EVP_PKEY_missing_parameters(pk) == 0) |
477 | ret = gost2001_compute_public(ec) != 0; | ||
448 | BN_free(pk_num); | 478 | BN_free(pk_num); |
449 | 479 | ||
450 | return 1; | 480 | return ret; |
451 | } | 481 | } |
452 | 482 | ||
453 | static int priv_encode_gost01(PKCS8_PRIV_KEY_INFO * p8, const EVP_PKEY * pk) | 483 | static int |
484 | priv_encode_gost01(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) | ||
454 | { | 485 | { |
455 | ASN1_OBJECT *algobj = OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(pk->pkey.gost))); | 486 | ASN1_OBJECT *algobj = |
487 | OBJ_nid2obj(GostR3410_get_pk_digest(GOST_KEY_get_digest(pk->pkey.gost))); | ||
456 | ASN1_STRING *params = encode_gost01_algor_params(pk); | 488 | ASN1_STRING *params = encode_gost01_algor_params(pk); |
457 | unsigned char *priv_buf = NULL; | 489 | unsigned char *priv_buf = NULL; |
458 | int priv_len; | 490 | int priv_len; |
459 | |||
460 | ASN1_INTEGER *asn1key = NULL; | 491 | ASN1_INTEGER *asn1key = NULL; |
461 | if (!params) { | 492 | |
493 | if (params == NULL) | ||
494 | return 0; | ||
495 | |||
496 | asn1key = BN_to_ASN1_INTEGER(GOST_KEY_get0_private_key(pk->pkey.gost), | ||
497 | NULL); | ||
498 | if (asn1key == NULL) { | ||
499 | ASN1_STRING_free(params); | ||
462 | return 0; | 500 | return 0; |
463 | } | 501 | } |
464 | asn1key = BN_to_ASN1_INTEGER(GOST_KEY_get0_private_key(pk->pkey.gost), NULL); | ||
465 | priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf); | 502 | priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf); |
466 | ASN1_INTEGER_free(asn1key); | 503 | ASN1_INTEGER_free(asn1key); |
467 | return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, | 504 | return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, priv_buf, |
468 | priv_buf, priv_len); | 505 | priv_len); |
469 | } | 506 | } |
470 | 507 | ||
471 | static int param_encode_gost01(const EVP_PKEY * pkey, unsigned char **pder) | 508 | static int |
509 | param_encode_gost01(const EVP_PKEY *pkey, unsigned char **pder) | ||
472 | { | 510 | { |
473 | ASN1_STRING *params = encode_gost01_algor_params(pkey); | 511 | ASN1_STRING *params = encode_gost01_algor_params(pkey); |
474 | int len; | 512 | int len; |
475 | if (!params) | 513 | |
514 | if (params == NULL) | ||
476 | return 0; | 515 | return 0; |
477 | len = params->length; | 516 | len = params->length; |
478 | if (pder) | 517 | if (pder != NULL) |
479 | memcpy(*pder, params->data, params->length); | 518 | memcpy(*pder, params->data, params->length); |
480 | ASN1_STRING_free(params); | 519 | ASN1_STRING_free(params); |
481 | return len; | 520 | return len; |
482 | } | 521 | } |
483 | 522 | ||
484 | static int param_decode_gost01(EVP_PKEY * pkey, const unsigned char **pder, | 523 | static int |
485 | int derlen) | 524 | param_decode_gost01(EVP_PKEY *pkey, const unsigned char **pder, int derlen) |
486 | { | 525 | { |
487 | ASN1_OBJECT *obj = NULL; | 526 | ASN1_OBJECT *obj = NULL; |
488 | int nid; | 527 | int nid; |
489 | GOST_KEY *ec; | 528 | GOST_KEY *ec; |
490 | EC_GROUP *group; | 529 | EC_GROUP *group; |
530 | int ret; | ||
491 | 531 | ||
492 | /* New format */ | 532 | /* New format */ |
493 | if ((V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED) == **pder) | 533 | if ((V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED) == **pder) |
@@ -522,67 +562,85 @@ static int param_decode_gost01(EVP_PKEY * pkey, const unsigned char **pder, | |||
522 | return 0; | 562 | return 0; |
523 | } | 563 | } |
524 | EC_GROUP_free(group); | 564 | EC_GROUP_free(group); |
525 | if (GOST_KEY_set_digest(ec, NID_id_GostR3411_94_CryptoProParamSet) == 0) { | 565 | if (GOST_KEY_set_digest(ec, |
566 | NID_id_GostR3411_94_CryptoProParamSet) == 0) { | ||
526 | GOSTerr(GOST_F_PARAM_DECODE_GOST01, GOST_R_INVALID_DIGEST_TYPE); | 567 | GOSTerr(GOST_F_PARAM_DECODE_GOST01, GOST_R_INVALID_DIGEST_TYPE); |
527 | GOST_KEY_free(ec); | 568 | GOST_KEY_free(ec); |
528 | return 0; | 569 | return 0; |
529 | } | 570 | } |
530 | EVP_PKEY_assign_GOST(pkey, ec); | 571 | ret = EVP_PKEY_assign_GOST(pkey, ec); |
531 | return 1; | 572 | if (ret == 0) |
573 | GOST_KEY_free(ec); | ||
574 | return ret; | ||
532 | } | 575 | } |
533 | 576 | ||
534 | static int param_missing_gost01(const EVP_PKEY * pk) | 577 | static int |
578 | param_missing_gost01(const EVP_PKEY *pk) | ||
535 | { | 579 | { |
536 | const GOST_KEY *ec = pk->pkey.gost; | 580 | const GOST_KEY *ec = pk->pkey.gost; |
537 | if (!ec) | 581 | |
582 | if (ec == NULL) | ||
538 | return 1; | 583 | return 1; |
539 | if (!GOST_KEY_get0_group(ec)) | 584 | if (GOST_KEY_get0_group(ec) == NULL) |
540 | return 1; | 585 | return 1; |
541 | if (GOST_KEY_get_digest(ec) == NID_undef) | 586 | if (GOST_KEY_get_digest(ec) == NID_undef) |
542 | return 1; | 587 | return 1; |
543 | return 0; | 588 | return 0; |
544 | } | 589 | } |
545 | 590 | ||
546 | static int param_copy_gost01(EVP_PKEY * to, const EVP_PKEY * from) | 591 | static int |
592 | param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) | ||
547 | { | 593 | { |
548 | GOST_KEY *eto = to->pkey.gost; | 594 | GOST_KEY *eto = to->pkey.gost; |
549 | const GOST_KEY *efrom = from->pkey.gost; | 595 | const GOST_KEY *efrom = from->pkey.gost; |
596 | int ret = 0; | ||
597 | |||
550 | if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { | 598 | if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { |
551 | GOSTerr(GOST_F_PARAM_COPY_GOST01, | 599 | GOSTerr(GOST_F_PARAM_COPY_GOST01, |
552 | GOST_R_INCOMPATIBLE_ALGORITHMS); | 600 | GOST_R_INCOMPATIBLE_ALGORITHMS); |
553 | return 0; | 601 | return 0; |
554 | } | 602 | } |
555 | if (!efrom) { | 603 | if (efrom == NULL) { |
556 | GOSTerr(GOST_F_PARAM_COPY_GOST01, | 604 | GOSTerr(GOST_F_PARAM_COPY_GOST01, |
557 | GOST_R_KEY_PARAMETERS_MISSING); | 605 | GOST_R_KEY_PARAMETERS_MISSING); |
558 | return 0; | 606 | return 0; |
559 | } | 607 | } |
560 | if (!eto) { | 608 | if (eto) { |
561 | eto = GOST_KEY_new(); | 609 | eto = GOST_KEY_new(); |
562 | EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto); | 610 | if (eto == NULL) { |
611 | GOSTerr(GOST_F_PARAM_COPY_GOST01, | ||
612 | ERR_R_MALLOC_FAILURE); | ||
613 | return 0; | ||
614 | } | ||
615 | if (EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto) == 0) { | ||
616 | GOST_KEY_free(eto); | ||
617 | return 0; | ||
618 | } | ||
563 | } | 619 | } |
564 | GOST_KEY_set_group(eto, GOST_KEY_get0_group(efrom)); | 620 | GOST_KEY_set_group(eto, GOST_KEY_get0_group(efrom)); |
565 | GOST_KEY_set_digest(eto, GOST_KEY_get_digest(efrom)); | 621 | GOST_KEY_set_digest(eto, GOST_KEY_get_digest(efrom)); |
566 | if (GOST_KEY_get0_private_key(eto)) { | 622 | if (GOST_KEY_get0_private_key(eto) != NULL) |
567 | gost2001_compute_public(eto); | 623 | ret = gost2001_compute_public(eto); |
568 | } | 624 | |
569 | return 1; | 625 | return ret; |
570 | } | 626 | } |
571 | 627 | ||
572 | static int param_cmp_gost01(const EVP_PKEY * a, const EVP_PKEY * b) | 628 | static int |
629 | param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) | ||
573 | { | 630 | { |
574 | if (EC_GROUP_get_curve_name(GOST_KEY_get0_group(a->pkey.gost)) != | 631 | if (EC_GROUP_get_curve_name(GOST_KEY_get0_group(a->pkey.gost)) != |
575 | EC_GROUP_get_curve_name(GOST_KEY_get0_group(b->pkey.gost))) { | 632 | EC_GROUP_get_curve_name(GOST_KEY_get0_group(b->pkey.gost))) |
576 | return 0; | 633 | return 0; |
577 | } | 634 | |
578 | if (GOST_KEY_get_digest(a->pkey.gost) != | 635 | if (GOST_KEY_get_digest(a->pkey.gost) != |
579 | GOST_KEY_get_digest(b->pkey.gost)) | 636 | GOST_KEY_get_digest(b->pkey.gost)) |
580 | return 0; | 637 | return 0; |
581 | return 1; | ||
582 | 638 | ||
639 | return 1; | ||
583 | } | 640 | } |
584 | 641 | ||
585 | static int pkey_ctrl_gost01(EVP_PKEY * pkey, int op, long arg1, void *arg2) | 642 | static int |
643 | pkey_ctrl_gost01(EVP_PKEY *pkey, int op, long arg1, void *arg2) | ||
586 | { | 644 | { |
587 | X509_ALGOR *alg1 = NULL, *alg2 = NULL, *alg3 = NULL; | 645 | X509_ALGOR *alg1 = NULL, *alg2 = NULL, *alg3 = NULL; |
588 | int digest = GOST_KEY_get_digest(pkey->pkey.gost); | 646 | int digest = GOST_KEY_get_digest(pkey->pkey.gost); |
diff --git a/src/lib/libssl/src/crypto/gost/gostr341001_key.c b/src/lib/libssl/src/crypto/gost/gostr341001_key.c index b236dde28a..2405722ddd 100644 --- a/src/lib/libssl/src/crypto/gost/gostr341001_key.c +++ b/src/lib/libssl/src/crypto/gost/gostr341001_key.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: gostr341001_key.c,v 1.2 2014/11/09 23:06:52 miod Exp $ */ | 1 | /* $OpenBSD: gostr341001_key.c,v 1.3 2014/11/13 20:29:55 miod Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> |
4 | * Copyright (c) 2005-2006 Cryptocom LTD | 4 | * Copyright (c) 2005-2006 Cryptocom LTD |
@@ -176,45 +176,47 @@ err: | |||
176 | return (ok); | 176 | return (ok); |
177 | } | 177 | } |
178 | 178 | ||
179 | int GOST_KEY_set_public_key_affine_coordinates(GOST_KEY * key, BIGNUM * x, BIGNUM * y) | 179 | int |
180 | GOST_KEY_set_public_key_affine_coordinates(GOST_KEY *key, BIGNUM *x, BIGNUM *y) | ||
180 | { | 181 | { |
181 | BN_CTX *ctx = NULL; | 182 | BN_CTX *ctx = NULL; |
182 | BIGNUM *tx, *ty; | 183 | BIGNUM *tx, *ty; |
183 | EC_POINT *point = NULL; | 184 | EC_POINT *point = NULL; |
184 | int ok = 0; | 185 | int ok = 0; |
185 | 186 | ||
186 | if (!key || !key->group || !x || !y) { | 187 | if (key == NULL || key->group == NULL || x == NULL || y == NULL) { |
187 | GOSTerr(GOST_F_GOST_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, | 188 | GOSTerr(GOST_F_GOST_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, |
188 | ERR_R_PASSED_NULL_PARAMETER); | 189 | ERR_R_PASSED_NULL_PARAMETER); |
189 | return 0; | 190 | return 0; |
190 | } | 191 | } |
191 | ctx = BN_CTX_new(); | 192 | ctx = BN_CTX_new(); |
192 | if (!ctx) | 193 | if (ctx == NULL) |
193 | goto err; | 194 | goto err; |
194 | 195 | ||
195 | point = EC_POINT_new(key->group); | 196 | point = EC_POINT_new(key->group); |
196 | 197 | if (point == NULL) | |
197 | if (!point) | ||
198 | goto err; | 198 | goto err; |
199 | 199 | ||
200 | tx = BN_CTX_get(ctx); | 200 | tx = BN_CTX_get(ctx); |
201 | ty = BN_CTX_get(ctx); | 201 | ty = BN_CTX_get(ctx); |
202 | if (!EC_POINT_set_affine_coordinates_GFp(key->group, point, | 202 | if (ty == NULL) |
203 | x, y, ctx)) | 203 | goto err; |
204 | if (EC_POINT_set_affine_coordinates_GFp(key->group, point, x, y, | ||
205 | ctx) == 0) | ||
204 | goto err; | 206 | goto err; |
205 | if (!EC_POINT_get_affine_coordinates_GFp(key->group, point, | 207 | if (EC_POINT_get_affine_coordinates_GFp(key->group, point, tx, ty, |
206 | tx, ty, ctx)) | 208 | ctx) == 0) |
207 | goto err; | 209 | goto err; |
208 | /* | 210 | /* |
209 | * Check if retrieved coordinates match originals: if not values are | 211 | * Check if retrieved coordinates match originals: if not, values are |
210 | * out of range. | 212 | * out of range. |
211 | */ | 213 | */ |
212 | if (BN_cmp(x, tx) || BN_cmp(y, ty)) { | 214 | if (BN_cmp(x, tx) != 0 || BN_cmp(y, ty) != 0) { |
213 | GOSTerr(GOST_F_GOST_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, | 215 | GOSTerr(GOST_F_GOST_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, |
214 | EC_R_COORDINATES_OUT_OF_RANGE); | 216 | EC_R_COORDINATES_OUT_OF_RANGE); |
215 | goto err; | 217 | goto err; |
216 | } | 218 | } |
217 | if (!GOST_KEY_set_public_key(key, point)) | 219 | if (GOST_KEY_set_public_key(key, point) == 0) |
218 | goto err; | 220 | goto err; |
219 | 221 | ||
220 | if (GOST_KEY_check_key(key) == 0) | 222 | if (GOST_KEY_check_key(key) == 0) |
diff --git a/src/lib/libssl/src/crypto/gost/gostr341001_pmeth.c b/src/lib/libssl/src/crypto/gost/gostr341001_pmeth.c index afcf8f973a..859c0884d6 100644 --- a/src/lib/libssl/src/crypto/gost/gostr341001_pmeth.c +++ b/src/lib/libssl/src/crypto/gost/gostr341001_pmeth.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: gostr341001_pmeth.c,v 1.5 2014/11/09 23:06:52 miod Exp $ */ | 1 | /* $OpenBSD: gostr341001_pmeth.c,v 1.6 2014/11/13 20:29:55 miod Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> | 3 | * Copyright (c) 2014 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> |
4 | * Copyright (c) 2005-2006 Cryptocom LTD | 4 | * Copyright (c) 2005-2006 Cryptocom LTD |
@@ -133,17 +133,19 @@ struct gost_pmeth_data { | |||
133 | int sig_format; | 133 | int sig_format; |
134 | }; | 134 | }; |
135 | 135 | ||
136 | static int pkey_gost01_init(EVP_PKEY_CTX * ctx) | 136 | static int |
137 | pkey_gost01_init(EVP_PKEY_CTX *ctx) | ||
137 | { | 138 | { |
138 | struct gost_pmeth_data *data; | 139 | struct gost_pmeth_data *data; |
139 | EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); | 140 | EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); |
140 | data = malloc(sizeof(struct gost_pmeth_data)); | 141 | |
141 | if (!data) | 142 | data = calloc(1, sizeof(struct gost_pmeth_data)); |
143 | if (data == NULL) | ||
142 | return 0; | 144 | return 0; |
143 | 145 | ||
144 | memset(data, 0, sizeof(struct gost_pmeth_data)); | 146 | if (pkey != NULL && pkey->pkey.gost != NULL) { |
145 | if (pkey && pkey->pkey.gost) { | 147 | data->sign_param_nid = |
146 | data->sign_param_nid = EC_GROUP_get_curve_name(GOST_KEY_get0_group(pkey->pkey.gost)); | 148 | EC_GROUP_get_curve_name(GOST_KEY_get0_group(pkey->pkey.gost)); |
147 | data->digest_nid = GOST_KEY_get_digest(pkey->pkey.gost); | 149 | data->digest_nid = GOST_KEY_get_digest(pkey->pkey.gost); |
148 | } | 150 | } |
149 | EVP_PKEY_CTX_set_data(ctx, data); | 151 | EVP_PKEY_CTX_set_data(ctx, data); |
@@ -151,85 +153,95 @@ static int pkey_gost01_init(EVP_PKEY_CTX * ctx) | |||
151 | } | 153 | } |
152 | 154 | ||
153 | /* Copies contents of gost_pmeth_data structure */ | 155 | /* Copies contents of gost_pmeth_data structure */ |
154 | static int pkey_gost01_copy(EVP_PKEY_CTX * dst, EVP_PKEY_CTX * src) | 156 | static int |
157 | pkey_gost01_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) | ||
155 | { | 158 | { |
156 | struct gost_pmeth_data *dst_data, *src_data; | 159 | struct gost_pmeth_data *dst_data, *src_data; |
157 | if (!pkey_gost01_init(dst)) { | 160 | |
161 | if (pkey_gost01_init(dst) == 0) | ||
158 | return 0; | 162 | return 0; |
159 | } | 163 | |
160 | src_data = EVP_PKEY_CTX_get_data(src); | 164 | src_data = EVP_PKEY_CTX_get_data(src); |
161 | dst_data = EVP_PKEY_CTX_get_data(dst); | 165 | dst_data = EVP_PKEY_CTX_get_data(dst); |
162 | *dst_data = *src_data; | 166 | *dst_data = *src_data; |
163 | if (src_data->shared_ukm) { | 167 | if (src_data->shared_ukm != NULL) |
164 | dst_data->shared_ukm = NULL; | 168 | dst_data->shared_ukm = NULL; |
165 | } | ||
166 | return 1; | 169 | return 1; |
167 | } | 170 | } |
168 | 171 | ||
169 | /* Frees up gost_pmeth_data structure */ | 172 | /* Frees up gost_pmeth_data structure */ |
170 | static void pkey_gost01_cleanup(EVP_PKEY_CTX * ctx) | 173 | static void |
174 | pkey_gost01_cleanup(EVP_PKEY_CTX *ctx) | ||
171 | { | 175 | { |
172 | struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); | 176 | struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); |
177 | |||
173 | free(data->shared_ukm); | 178 | free(data->shared_ukm); |
174 | free(data); | 179 | free(data); |
175 | } | 180 | } |
176 | 181 | ||
177 | static int pkey_gost01_paramgen(EVP_PKEY_CTX * ctx, EVP_PKEY * pkey) | 182 | static int |
183 | pkey_gost01_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) | ||
178 | { | 184 | { |
179 | struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); | 185 | struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); |
180 | EC_GROUP *group; | 186 | EC_GROUP *group; |
181 | GOST_KEY *gost; | 187 | GOST_KEY *gost; |
182 | int ret; | 188 | int ret; |
183 | 189 | ||
184 | if (data->sign_param_nid == NID_undef || data->digest_nid == NID_undef) { | 190 | if (data->sign_param_nid == NID_undef || |
191 | data->digest_nid == NID_undef) { | ||
185 | GOSTerr(GOST_F_PKEY_GOST01_PARAMGEN, GOST_R_NO_PARAMETERS_SET); | 192 | GOSTerr(GOST_F_PKEY_GOST01_PARAMGEN, GOST_R_NO_PARAMETERS_SET); |
186 | return 0; | 193 | return 0; |
187 | } | 194 | } |
188 | 195 | ||
189 | group = EC_GROUP_new_by_curve_name(data->sign_param_nid); | 196 | group = EC_GROUP_new_by_curve_name(data->sign_param_nid); |
190 | if (!group) | 197 | if (group == NULL) |
191 | return 0; | 198 | return 0; |
192 | 199 | ||
193 | EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); | 200 | EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); |
194 | 201 | ||
195 | gost = GOST_KEY_new(); | 202 | gost = GOST_KEY_new(); |
196 | if (!gost) | 203 | if (gost == NULL) |
197 | return 0; | 204 | return 0; |
198 | 205 | ||
199 | if (!GOST_KEY_set_digest(gost, data->digest_nid)) | 206 | if (GOST_KEY_set_digest(gost, data->digest_nid) == 0) |
200 | return 0; | 207 | return 0; |
201 | 208 | ||
202 | ret = GOST_KEY_set_group(gost, group); | 209 | ret = GOST_KEY_set_group(gost, group); |
203 | if (ret) | 210 | if (ret != 0) |
204 | EVP_PKEY_assign_GOST(pkey, gost); | 211 | ret = EVP_PKEY_assign_GOST(pkey, gost); |
205 | else | 212 | if (ret == 0) |
206 | GOST_KEY_free(gost); | 213 | GOST_KEY_free(gost); |
207 | 214 | ||
208 | EC_GROUP_free(group); | 215 | EC_GROUP_free(group); |
209 | return ret; | 216 | return ret; |
210 | } | 217 | } |
211 | 218 | ||
212 | static int pkey_gost01_keygen(EVP_PKEY_CTX * ctx, EVP_PKEY * pkey) | 219 | static int |
220 | pkey_gost01_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) | ||
213 | { | 221 | { |
214 | if (!pkey_gost01_paramgen(ctx, pkey)) | 222 | if (pkey_gost01_paramgen(ctx, pkey) == 0) |
215 | return 0; | 223 | return 0; |
216 | gost2001_keygen(pkey->pkey.gost); | 224 | return gost2001_keygen(pkey->pkey.gost) != 0; |
217 | return 1; | ||
218 | } | 225 | } |
219 | 226 | ||
220 | static int pkey_gost01_sign(EVP_PKEY_CTX * ctx, unsigned char *sig, | 227 | static int |
221 | size_t * siglen, const unsigned char *tbs, | 228 | pkey_gost01_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, |
222 | size_t tbs_len) | 229 | const unsigned char *tbs, size_t tbs_len) |
223 | { | 230 | { |
224 | ECDSA_SIG *unpacked_sig = NULL; | 231 | ECDSA_SIG *unpacked_sig = NULL; |
225 | EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); | 232 | EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); |
226 | struct gost_pmeth_data *pctx = EVP_PKEY_CTX_get_data(ctx); | 233 | struct gost_pmeth_data *pctx = EVP_PKEY_CTX_get_data(ctx); |
227 | BIGNUM *md; | 234 | BIGNUM *md; |
228 | size_t size = GOST_KEY_get_size(pkey->pkey.gost); | 235 | size_t size; |
236 | int ret; | ||
237 | |||
238 | if (pkey == NULL || pkey->pkey.gost == NULL) | ||
239 | return 0; | ||
240 | size = GOST_KEY_get_size(pkey->pkey.gost); | ||
229 | 241 | ||
230 | if (!siglen) | 242 | if (siglen == NULL) |
231 | return 0; | 243 | return 0; |
232 | if (!sig) { | 244 | if (sig == NULL) { |
233 | *siglen = 2 * size; | 245 | *siglen = 2 * size; |
234 | return 1; | 246 | return 1; |
235 | } else if (*siglen < 2 * size) { | 247 | } else if (*siglen < 2 * size) { |
@@ -238,24 +250,32 @@ static int pkey_gost01_sign(EVP_PKEY_CTX * ctx, unsigned char *sig, | |||
238 | } | 250 | } |
239 | OPENSSL_assert(tbs_len == 32 || tbs_len == 64); | 251 | OPENSSL_assert(tbs_len == 32 || tbs_len == 64); |
240 | md = GOST_le2bn(tbs, tbs_len, NULL); | 252 | md = GOST_le2bn(tbs, tbs_len, NULL); |
253 | if (md == NULL) | ||
254 | return 0; | ||
241 | unpacked_sig = gost2001_do_sign(md, pkey->pkey.gost); | 255 | unpacked_sig = gost2001_do_sign(md, pkey->pkey.gost); |
242 | if (!unpacked_sig) { | 256 | BN_free(md); |
257 | if (unpacked_sig == NULL) { | ||
243 | return 0; | 258 | return 0; |
244 | } | 259 | } |
245 | switch (pctx->sig_format) { | 260 | switch (pctx->sig_format) { |
246 | case GOST_SIG_FORMAT_SR_BE: | 261 | case GOST_SIG_FORMAT_SR_BE: |
247 | return pack_signature_cp(unpacked_sig, size, sig, siglen); | 262 | ret = pack_signature_cp(unpacked_sig, size, sig, siglen); |
263 | break; | ||
248 | case GOST_SIG_FORMAT_RS_LE: | 264 | case GOST_SIG_FORMAT_RS_LE: |
249 | return pack_signature_le(unpacked_sig, size, sig, siglen); | 265 | ret = pack_signature_le(unpacked_sig, size, sig, siglen); |
266 | break; | ||
250 | default: | 267 | default: |
251 | ECDSA_SIG_free(unpacked_sig); | 268 | ret = -1; |
252 | return -1; | 269 | break; |
253 | } | 270 | } |
271 | if (ret <= 0) | ||
272 | ECDSA_SIG_free(unpacked_sig); | ||
273 | return ret; | ||
254 | } | 274 | } |
255 | 275 | ||
256 | static int pkey_gost01_verify(EVP_PKEY_CTX * ctx, const unsigned char *sig, | 276 | static int |
257 | size_t siglen, const unsigned char *tbs, | 277 | pkey_gost01_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, |
258 | size_t tbs_len) | 278 | const unsigned char *tbs, size_t tbs_len) |
259 | { | 279 | { |
260 | int ok = 0; | 280 | int ok = 0; |
261 | EVP_PKEY *pub_key = EVP_PKEY_CTX_get0_pkey(ctx); | 281 | EVP_PKEY *pub_key = EVP_PKEY_CTX_get0_pkey(ctx); |
@@ -286,24 +306,33 @@ err: | |||
286 | return ok; | 306 | return ok; |
287 | } | 307 | } |
288 | 308 | ||
289 | static int gost01_VKO_key(EVP_PKEY * pub_key, EVP_PKEY * priv_key, | 309 | static int |
290 | const unsigned char *ukm, unsigned char *key) | 310 | gost01_VKO_key(EVP_PKEY *pub_key, EVP_PKEY *priv_key, const unsigned char *ukm, |
311 | unsigned char *key) | ||
291 | { | 312 | { |
292 | unsigned char hashbuf[128]; | 313 | unsigned char hashbuf[128]; |
293 | int digest_nid; | 314 | int digest_nid; |
294 | int ret; | 315 | int ret = 0; |
295 | BN_CTX *ctx = BN_CTX_new(); | 316 | BN_CTX *ctx = BN_CTX_new(); |
296 | BIGNUM *UKM, *X, *Y; | 317 | BIGNUM *UKM, *X, *Y; |
297 | 318 | ||
319 | if (ctx == NULL) | ||
320 | return 0; | ||
321 | |||
298 | BN_CTX_start(ctx); | 322 | BN_CTX_start(ctx); |
299 | UKM = BN_CTX_get(ctx); | 323 | UKM = BN_CTX_get(ctx); |
300 | X = BN_CTX_get(ctx); | 324 | X = BN_CTX_get(ctx); |
301 | Y = BN_CTX_get(ctx); | 325 | Y = BN_CTX_get(ctx); |
326 | if (Y == NULL) | ||
327 | goto err; | ||
302 | 328 | ||
303 | GOST_le2bn(ukm, 8, UKM); | 329 | GOST_le2bn(ukm, 8, UKM); |
304 | 330 | ||
305 | digest_nid = GOST_KEY_get_digest(priv_key->pkey.gost); | 331 | digest_nid = GOST_KEY_get_digest(priv_key->pkey.gost); |
306 | VKO_compute_key(X, Y, pub_key->pkey.gost, priv_key->pkey.gost, UKM); | 332 | if (VKO_compute_key(X, Y, pub_key->pkey.gost, priv_key->pkey.gost, |
333 | UKM) == 0) | ||
334 | goto err; | ||
335 | |||
307 | switch (digest_nid) { | 336 | switch (digest_nid) { |
308 | case NID_id_GostR3411_94_CryptoProParamSet: | 337 | case NID_id_GostR3411_94_CryptoProParamSet: |
309 | GOST_bn2le(X, hashbuf, 32); | 338 | GOST_bn2le(X, hashbuf, 32); |
@@ -327,14 +356,15 @@ static int gost01_VKO_key(EVP_PKEY * pub_key, EVP_PKEY * priv_key, | |||
327 | ret = -2; | 356 | ret = -2; |
328 | break; | 357 | break; |
329 | } | 358 | } |
359 | err: | ||
330 | BN_CTX_end(ctx); | 360 | BN_CTX_end(ctx); |
331 | BN_CTX_free(ctx); | 361 | BN_CTX_free(ctx); |
332 | return ret; | 362 | return ret; |
333 | } | 363 | } |
334 | 364 | ||
335 | int pkey_gost01_decrypt(EVP_PKEY_CTX * pctx, unsigned char *key, | 365 | int |
336 | size_t * key_len, const unsigned char *in, | 366 | pkey_gost01_decrypt(EVP_PKEY_CTX *pctx, unsigned char *key, size_t *key_len, |
337 | size_t in_len) | 367 | const unsigned char *in, size_t in_len) |
338 | { | 368 | { |
339 | const unsigned char *p = in; | 369 | const unsigned char *p = in; |
340 | EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx); | 370 | EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx); |
@@ -387,26 +417,26 @@ int pkey_gost01_decrypt(EVP_PKEY_CTX * pctx, unsigned char *key, | |||
387 | memcpy(wrappedKey + 8, gkt->key_info->encrypted_key->data, 32); | 417 | memcpy(wrappedKey + 8, gkt->key_info->encrypted_key->data, 32); |
388 | OPENSSL_assert(gkt->key_info->imit->length == 4); | 418 | OPENSSL_assert(gkt->key_info->imit->length == 4); |
389 | memcpy(wrappedKey + 40, gkt->key_info->imit->data, 4); | 419 | memcpy(wrappedKey + 40, gkt->key_info->imit->data, 4); |
390 | gost01_VKO_key(peerkey, priv, wrappedKey, sharedKey); | 420 | if (gost01_VKO_key(peerkey, priv, wrappedKey, sharedKey) <= 0) |
391 | if (!gost_key_unwrap_crypto_pro(nid, sharedKey, wrappedKey, key)) { | 421 | goto err; |
422 | if (gost_key_unwrap_crypto_pro(nid, sharedKey, wrappedKey, key) == 0) { | ||
392 | GOSTerr(GOST_F_PKEY_GOST01_DECRYPT, | 423 | GOSTerr(GOST_F_PKEY_GOST01_DECRYPT, |
393 | GOST_R_ERROR_COMPUTING_SHARED_KEY); | 424 | GOST_R_ERROR_COMPUTING_SHARED_KEY); |
394 | goto err; | 425 | goto err; |
395 | } | 426 | } |
396 | 427 | ||
397 | ret = 1; | 428 | ret = 1; |
398 | err: | 429 | err: |
399 | if (eph_key) | 430 | EVP_PKEY_free(eph_key); |
400 | EVP_PKEY_free(eph_key); | 431 | GOST_KEY_TRANSPORT_free(gkt); |
401 | if (gkt) | ||
402 | GOST_KEY_TRANSPORT_free(gkt); | ||
403 | return ret; | 432 | return ret; |
404 | } | 433 | } |
405 | 434 | ||
406 | int pkey_gost01_derive(EVP_PKEY_CTX * ctx, unsigned char *key, | 435 | int |
407 | size_t * keylen) | 436 | pkey_gost01_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) |
408 | { | 437 | { |
409 | /* Public key of peer in the ctx field peerkey | 438 | /* |
439 | * Public key of peer in the ctx field peerkey | ||
410 | * Our private key in the ctx pkey | 440 | * Our private key in the ctx pkey |
411 | * ukm is in the algorithm specific context data | 441 | * ukm is in the algorithm specific context data |
412 | */ | 442 | */ |
@@ -424,86 +454,98 @@ int pkey_gost01_derive(EVP_PKEY_CTX * ctx, unsigned char *key, | |||
424 | return 32; | 454 | return 32; |
425 | } | 455 | } |
426 | 456 | ||
427 | gost01_VKO_key(peer_key, my_key, data->shared_ukm, key); | 457 | if (gost01_VKO_key(peer_key, my_key, data->shared_ukm, key) <= 0) |
458 | return 0; | ||
459 | |||
428 | *keylen = 32; | 460 | *keylen = 32; |
429 | return 1; | 461 | return 1; |
430 | } | 462 | } |
431 | 463 | ||
432 | int pkey_gost01_encrypt(EVP_PKEY_CTX * pctx, unsigned char *out, | 464 | int |
433 | size_t * out_len, const unsigned char *key, | 465 | pkey_gost01_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len, |
434 | size_t key_len) | 466 | const unsigned char *key, size_t key_len) |
435 | { | 467 | { |
436 | GOST_KEY_TRANSPORT *gkt = NULL; | 468 | GOST_KEY_TRANSPORT *gkt = NULL; |
437 | EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx); | 469 | EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx); |
438 | struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx); | 470 | struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx); |
439 | unsigned char ukm[8], shared_key[32], crypted_key[44]; | 471 | unsigned char ukm[8], shared_key[32], crypted_key[44]; |
440 | int ret = 0; | 472 | int ret = 0; |
441 | int key_is_ephemeral = 1; | 473 | int key_is_ephemeral; |
442 | EVP_PKEY *sec_key = EVP_PKEY_CTX_get0_peerkey(pctx); | 474 | EVP_PKEY *sec_key = EVP_PKEY_CTX_get0_peerkey(pctx); |
443 | int nid = NID_id_Gost28147_89_CryptoPro_A_ParamSet; | 475 | int nid = NID_id_Gost28147_89_CryptoPro_A_ParamSet; |
444 | 476 | ||
445 | if (data->shared_ukm) { | 477 | if (data->shared_ukm != NULL) { |
446 | memcpy(ukm, data->shared_ukm, 8); | 478 | memcpy(ukm, data->shared_ukm, 8); |
447 | } else if (out) { | 479 | } else /* if (out != NULL) */ { |
448 | arc4random_buf(ukm, 8); | 480 | arc4random_buf(ukm, 8); |
449 | } | 481 | } |
450 | /* Check for private key in the peer_key of context */ | 482 | /* Check for private key in the peer_key of context */ |
451 | if (sec_key) { | 483 | if (sec_key) { |
452 | key_is_ephemeral = 0; | 484 | key_is_ephemeral = 0; |
453 | if (!GOST_KEY_get0_private_key(sec_key->pkey.gost)) { | 485 | if (GOST_KEY_get0_private_key(sec_key->pkey.gost) == 0) { |
454 | GOSTerr(GOST_F_PKEY_GOST01_ENCRYPT, | 486 | GOSTerr(GOST_F_PKEY_GOST01_ENCRYPT, |
455 | GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR); | 487 | GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR); |
456 | goto err; | 488 | goto err; |
457 | } | 489 | } |
458 | } else { | 490 | } else { |
459 | key_is_ephemeral = 1; | 491 | key_is_ephemeral = 1; |
460 | if (out) { | 492 | if (out != NULL) { |
493 | GOST_KEY *tmp_key; | ||
494 | |||
461 | sec_key = EVP_PKEY_new(); | 495 | sec_key = EVP_PKEY_new(); |
462 | EVP_PKEY_assign(sec_key, EVP_PKEY_base_id(pubk), | 496 | if (sec_key == NULL) |
463 | GOST_KEY_new()); | 497 | goto err; |
464 | EVP_PKEY_copy_parameters(sec_key, pubk); | 498 | tmp_key = GOST_KEY_new(); |
465 | if (!gost2001_keygen(sec_key->pkey.gost)) { | 499 | if (tmp_key == NULL) |
500 | goto err; | ||
501 | if (EVP_PKEY_assign(sec_key, EVP_PKEY_base_id(pubk), | ||
502 | tmp_key) == 0) { | ||
503 | GOST_KEY_free(tmp_key); | ||
504 | goto err; | ||
505 | } | ||
506 | if (EVP_PKEY_copy_parameters(sec_key, pubk) == 0) | ||
507 | goto err; | ||
508 | if (gost2001_keygen(sec_key->pkey.gost) == 0) { | ||
466 | goto err; | 509 | goto err; |
467 | } | 510 | } |
468 | } | 511 | } |
469 | } | 512 | } |
470 | 513 | ||
471 | if (out) { | 514 | if (out != NULL) { |
472 | gost01_VKO_key(pubk, sec_key, ukm, shared_key); | 515 | if (gost01_VKO_key(pubk, sec_key, ukm, shared_key) <= 0) |
473 | gost_key_wrap_crypto_pro(nid, shared_key, ukm, key, crypted_key); | 516 | goto err; |
517 | gost_key_wrap_crypto_pro(nid, shared_key, ukm, key, | ||
518 | crypted_key); | ||
474 | } | 519 | } |
475 | gkt = GOST_KEY_TRANSPORT_new(); | 520 | gkt = GOST_KEY_TRANSPORT_new(); |
476 | if (!gkt) { | 521 | if (gkt == NULL) |
477 | goto err; | 522 | goto err; |
478 | } | 523 | if (ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, ukm, 8) == 0) |
479 | if (!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, ukm, 8)) { | ||
480 | goto err; | 524 | goto err; |
481 | } | 525 | if (ASN1_OCTET_STRING_set(gkt->key_info->imit, crypted_key + 40, |
482 | if (!ASN1_OCTET_STRING_set(gkt->key_info->imit, crypted_key + 40, 4)) { | 526 | 4) == 0) |
483 | goto err; | 527 | goto err; |
484 | } | 528 | if (ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key, crypted_key + 8, |
485 | if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key, crypted_key + 8, 32)) { | 529 | 32) == 0) |
486 | goto err; | 530 | goto err; |
487 | } | ||
488 | if (key_is_ephemeral) { | 531 | if (key_is_ephemeral) { |
489 | if (!X509_PUBKEY_set | 532 | if (X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key, |
490 | (&gkt->key_agreement_info->ephem_key, | 533 | out != NULL ? sec_key : pubk) == 0) { |
491 | out ? sec_key : pubk)) { | ||
492 | GOSTerr(GOST_F_PKEY_GOST01_ENCRYPT, | 534 | GOSTerr(GOST_F_PKEY_GOST01_ENCRYPT, |
493 | GOST_R_CANNOT_PACK_EPHEMERAL_KEY); | 535 | GOST_R_CANNOT_PACK_EPHEMERAL_KEY); |
494 | goto err; | 536 | goto err; |
495 | } | 537 | } |
496 | } | 538 | } |
497 | ASN1_OBJECT_free(gkt->key_agreement_info->cipher); | 539 | ASN1_OBJECT_free(gkt->key_agreement_info->cipher); |
498 | gkt->key_agreement_info->cipher = OBJ_nid2obj(nid); | 540 | gkt->key_agreement_info->cipher = OBJ_nid2obj(nid); |
499 | if (key_is_ephemeral && sec_key) | 541 | if (key_is_ephemeral) |
500 | EVP_PKEY_free(sec_key); | 542 | EVP_PKEY_free(sec_key); |
501 | if (!key_is_ephemeral) { | 543 | else { |
502 | /* Set control "public key from client certificate used" */ | 544 | /* Set control "public key from client certificate used" */ |
503 | if (EVP_PKEY_CTX_ctrl | 545 | if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, |
504 | (pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0) { | 546 | NULL) <= 0) { |
505 | GOSTerr(GOST_F_PKEY_GOST01_ENCRYPT, | 547 | GOSTerr(GOST_F_PKEY_GOST01_ENCRYPT, |
506 | GOST_R_CTRL_CALL_FAILED); | 548 | GOST_R_CTRL_CALL_FAILED); |
507 | goto err; | 549 | goto err; |
508 | } | 550 | } |
509 | } | 551 | } |
@@ -511,21 +553,26 @@ int pkey_gost01_encrypt(EVP_PKEY_CTX * pctx, unsigned char *out, | |||
511 | ret = 1; | 553 | ret = 1; |
512 | GOST_KEY_TRANSPORT_free(gkt); | 554 | GOST_KEY_TRANSPORT_free(gkt); |
513 | return ret; | 555 | return ret; |
514 | err: | 556 | |
515 | if (key_is_ephemeral && sec_key) | 557 | err: |
558 | if (key_is_ephemeral) | ||
516 | EVP_PKEY_free(sec_key); | 559 | EVP_PKEY_free(sec_key); |
517 | GOST_KEY_TRANSPORT_free(gkt); | 560 | GOST_KEY_TRANSPORT_free(gkt); |
518 | return -1; | 561 | return -1; |
519 | } | 562 | } |
520 | 563 | ||
521 | 564 | ||
522 | static int pkey_gost01_ctrl(EVP_PKEY_CTX * ctx, int type, int p1, void *p2) | 565 | static int |
566 | pkey_gost01_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) | ||
523 | { | 567 | { |
524 | struct gost_pmeth_data *pctx = EVP_PKEY_CTX_get_data(ctx); | 568 | struct gost_pmeth_data *pctx = EVP_PKEY_CTX_get_data(ctx); |
569 | |||
525 | switch (type) { | 570 | switch (type) { |
526 | case EVP_PKEY_CTRL_MD: | 571 | case EVP_PKEY_CTRL_MD: |
527 | if (EVP_MD_type(p2) != GostR3410_get_md_digest(pctx->digest_nid)) { | 572 | if (EVP_MD_type(p2) != |
528 | GOSTerr(GOST_F_PKEY_GOST01_CTRL, GOST_R_INVALID_DIGEST_TYPE); | 573 | GostR3410_get_md_digest(pctx->digest_nid)) { |
574 | GOSTerr(GOST_F_PKEY_GOST01_CTRL, | ||
575 | GOST_R_INVALID_DIGEST_TYPE); | ||
529 | return 0; | 576 | return 0; |
530 | } | 577 | } |
531 | pctx->md = p2; | 578 | pctx->md = p2; |
@@ -546,9 +593,19 @@ static int pkey_gost01_ctrl(EVP_PKEY_CTX * ctx, int type, int p1, void *p2) | |||
546 | return 1; | 593 | return 1; |
547 | 594 | ||
548 | case EVP_PKEY_CTRL_SET_IV: | 595 | case EVP_PKEY_CTRL_SET_IV: |
549 | pctx->shared_ukm = malloc((int)p1); | 596 | { |
550 | memcpy(pctx->shared_ukm, p2, (int)p1); | 597 | char *ukm = malloc(p1); |
598 | |||
599 | if (ukm == NULL) { | ||
600 | GOSTerr(GOST_F_PKEY_GOST01_CTRL, | ||
601 | ERR_R_MALLOC_FAILURE); | ||
602 | return 0; | ||
603 | } | ||
604 | memcpy(ukm, p2, p1); | ||
605 | free(pctx->shared_ukm); | ||
606 | pctx->shared_ukm = ukm; | ||
551 | return 1; | 607 | return 1; |
608 | } | ||
552 | 609 | ||
553 | case EVP_PKEY_CTRL_PEER_KEY: | 610 | case EVP_PKEY_CTRL_PEER_KEY: |
554 | if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */ | 611 | if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */ |