summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/gost/gost89imit_pmeth.c12
-rw-r--r--src/lib/libcrypto/gost/gost_locl.h4
-rw-r--r--src/lib/libcrypto/gost/gostr341001.c256
-rw-r--r--src/lib/libcrypto/gost/gostr341001_ameth.c222
-rw-r--r--src/lib/libcrypto/gost/gostr341001_key.c28
-rw-r--r--src/lib/libcrypto/gost/gostr341001_pmeth.c253
-rw-r--r--src/lib/libssl/src/crypto/gost/gost89imit_pmeth.c12
-rw-r--r--src/lib/libssl/src/crypto/gost/gost_locl.h4
-rw-r--r--src/lib/libssl/src/crypto/gost/gostr341001.c256
-rw-r--r--src/lib/libssl/src/crypto/gost/gostr341001_ameth.c222
-rw-r--r--src/lib/libssl/src/crypto/gost/gostr341001_key.c28
-rw-r--r--src/lib/libssl/src/crypto/gost/gostr341001_pmeth.c253
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
124static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) 128static int
129pkey_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);
99extern ECDSA_SIG *gost2001_do_sign(BIGNUM *md, GOST_KEY *eckey); 99extern ECDSA_SIG *gost2001_do_sign(BIGNUM *md, GOST_KEY *eckey);
100extern int gost2001_do_verify(BIGNUM *md, ECDSA_SIG *sig, GOST_KEY *ec); 100extern int gost2001_do_verify(BIGNUM *md, ECDSA_SIG *sig, GOST_KEY *ec);
101extern int gost2001_keygen(GOST_KEY *ec); 101extern int gost2001_keygen(GOST_KEY *ec);
102extern void VKO_compute_key(BIGNUM *X, BIGNUM *Y, const GOST_KEY *pkey, 102extern 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);
104extern BIGNUM *GOST_le2bn(const unsigned char *buf, size_t len, BIGNUM *bn); 104extern BIGNUM *GOST_le2bn(const unsigned char *buf, size_t len, BIGNUM *bn);
105extern int GOST_bn2le(BIGNUM *bn, unsigned char *buf, int len); 105extern 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 */
62BIGNUM *GOST_le2bn(const unsigned char * buf, size_t len, BIGNUM * bn) 62BIGNUM *
63GOST_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
76int GOST_bn2le(BIGNUM * bn, unsigned char * buf, int len) 78int
79GOST_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 99int
97int gost2001_compute_public(GOST_KEY * ec) 100gost2001_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) {
127err: 133err:
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
134ECDSA_SIG *gost2001_do_sign(BIGNUM * md, GOST_KEY * eckey) 144ECDSA_SIG *
145gost2001_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
209err: 238err:
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
217int gost2001_do_verify(BIGNUM * md, ECDSA_SIG * sig, GOST_KEY * ec) 251int
252gost2001_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: 318err:
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 */
278void VKO_compute_key(BIGNUM * X, BIGNUM * Y, 328int
279 const GOST_KEY * pkey, GOST_KEY * priv_key, 329VKO_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
361err:
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
301int gost2001_keygen(GOST_KEY * ec) 370int
371gost2001_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
394err:
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
242static int pub_encode_gost01(X509_PUBKEY * pub, const EVP_PKEY * pk) 241static int
242pub_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
312err:
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
311static int param_print_gost01(BIO * out, const EVP_PKEY * pkey, int indent, 320static int
312 ASN1_PCTX * pctx) 321param_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
324static int pub_print_gost01(BIO * out, const EVP_PKEY * pkey, int indent, 336static int
325 ASN1_PCTX * pctx) 337pub_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
378err:
379 BN_CTX_end(ctx);
380 BN_CTX_free(ctx);
381 return 0;
362} 382}
363 383
364static int priv_print_gost01(BIO * out, const EVP_PKEY * pkey, int indent, 384static int
365 ASN1_PCTX * pctx) 385priv_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
453static int priv_encode_gost01(PKCS8_PRIV_KEY_INFO * p8, const EVP_PKEY * pk) 483static int
484priv_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
471static int param_encode_gost01(const EVP_PKEY * pkey, unsigned char **pder) 508static int
509param_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
484static int param_decode_gost01(EVP_PKEY * pkey, const unsigned char **pder, 523static int
485 int derlen) 524param_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
534static int param_missing_gost01(const EVP_PKEY * pk) 577static int
578param_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
546static int param_copy_gost01(EVP_PKEY * to, const EVP_PKEY * from) 591static int
592param_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
572static int param_cmp_gost01(const EVP_PKEY * a, const EVP_PKEY * b) 628static int
629param_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
585static int pkey_ctrl_gost01(EVP_PKEY * pkey, int op, long arg1, void *arg2) 642static int
643pkey_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
179int GOST_KEY_set_public_key_affine_coordinates(GOST_KEY * key, BIGNUM * x, BIGNUM * y) 179int
180GOST_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
136static int pkey_gost01_init(EVP_PKEY_CTX * ctx) 136static int
137pkey_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 */
154static int pkey_gost01_copy(EVP_PKEY_CTX * dst, EVP_PKEY_CTX * src) 156static int
157pkey_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 */
170static void pkey_gost01_cleanup(EVP_PKEY_CTX * ctx) 173static void
174pkey_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
177static int pkey_gost01_paramgen(EVP_PKEY_CTX * ctx, EVP_PKEY * pkey) 182static int
183pkey_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
212static int pkey_gost01_keygen(EVP_PKEY_CTX * ctx, EVP_PKEY * pkey) 219static int
220pkey_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
220static int pkey_gost01_sign(EVP_PKEY_CTX * ctx, unsigned char *sig, 227static int
221 size_t * siglen, const unsigned char *tbs, 228pkey_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
256static int pkey_gost01_verify(EVP_PKEY_CTX * ctx, const unsigned char *sig, 276static int
257 size_t siglen, const unsigned char *tbs, 277pkey_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
289static int gost01_VKO_key(EVP_PKEY * pub_key, EVP_PKEY * priv_key, 309static int
290 const unsigned char *ukm, unsigned char *key) 310gost01_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 }
359err:
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
335int pkey_gost01_decrypt(EVP_PKEY_CTX * pctx, unsigned char *key, 365int
336 size_t * key_len, const unsigned char *in, 366pkey_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: 429err:
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
406int pkey_gost01_derive(EVP_PKEY_CTX * ctx, unsigned char *key, 435int
407 size_t * keylen) 436pkey_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
432int pkey_gost01_encrypt(EVP_PKEY_CTX * pctx, unsigned char *out, 464int
433 size_t * out_len, const unsigned char *key, 465pkey_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) 557err:
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
522static int pkey_gost01_ctrl(EVP_PKEY_CTX * ctx, int type, int p1, void *p2) 565static int
566pkey_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
124static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) 128static int
129pkey_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);
99extern ECDSA_SIG *gost2001_do_sign(BIGNUM *md, GOST_KEY *eckey); 99extern ECDSA_SIG *gost2001_do_sign(BIGNUM *md, GOST_KEY *eckey);
100extern int gost2001_do_verify(BIGNUM *md, ECDSA_SIG *sig, GOST_KEY *ec); 100extern int gost2001_do_verify(BIGNUM *md, ECDSA_SIG *sig, GOST_KEY *ec);
101extern int gost2001_keygen(GOST_KEY *ec); 101extern int gost2001_keygen(GOST_KEY *ec);
102extern void VKO_compute_key(BIGNUM *X, BIGNUM *Y, const GOST_KEY *pkey, 102extern 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);
104extern BIGNUM *GOST_le2bn(const unsigned char *buf, size_t len, BIGNUM *bn); 104extern BIGNUM *GOST_le2bn(const unsigned char *buf, size_t len, BIGNUM *bn);
105extern int GOST_bn2le(BIGNUM *bn, unsigned char *buf, int len); 105extern 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 */
62BIGNUM *GOST_le2bn(const unsigned char * buf, size_t len, BIGNUM * bn) 62BIGNUM *
63GOST_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
76int GOST_bn2le(BIGNUM * bn, unsigned char * buf, int len) 78int
79GOST_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 99int
97int gost2001_compute_public(GOST_KEY * ec) 100gost2001_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) {
127err: 133err:
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
134ECDSA_SIG *gost2001_do_sign(BIGNUM * md, GOST_KEY * eckey) 144ECDSA_SIG *
145gost2001_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
209err: 238err:
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
217int gost2001_do_verify(BIGNUM * md, ECDSA_SIG * sig, GOST_KEY * ec) 251int
252gost2001_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: 318err:
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 */
278void VKO_compute_key(BIGNUM * X, BIGNUM * Y, 328int
279 const GOST_KEY * pkey, GOST_KEY * priv_key, 329VKO_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
361err:
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
301int gost2001_keygen(GOST_KEY * ec) 370int
371gost2001_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
394err:
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
242static int pub_encode_gost01(X509_PUBKEY * pub, const EVP_PKEY * pk) 241static int
242pub_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
312err:
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
311static int param_print_gost01(BIO * out, const EVP_PKEY * pkey, int indent, 320static int
312 ASN1_PCTX * pctx) 321param_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
324static int pub_print_gost01(BIO * out, const EVP_PKEY * pkey, int indent, 336static int
325 ASN1_PCTX * pctx) 337pub_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
378err:
379 BN_CTX_end(ctx);
380 BN_CTX_free(ctx);
381 return 0;
362} 382}
363 383
364static int priv_print_gost01(BIO * out, const EVP_PKEY * pkey, int indent, 384static int
365 ASN1_PCTX * pctx) 385priv_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
453static int priv_encode_gost01(PKCS8_PRIV_KEY_INFO * p8, const EVP_PKEY * pk) 483static int
484priv_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
471static int param_encode_gost01(const EVP_PKEY * pkey, unsigned char **pder) 508static int
509param_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
484static int param_decode_gost01(EVP_PKEY * pkey, const unsigned char **pder, 523static int
485 int derlen) 524param_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
534static int param_missing_gost01(const EVP_PKEY * pk) 577static int
578param_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
546static int param_copy_gost01(EVP_PKEY * to, const EVP_PKEY * from) 591static int
592param_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
572static int param_cmp_gost01(const EVP_PKEY * a, const EVP_PKEY * b) 628static int
629param_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
585static int pkey_ctrl_gost01(EVP_PKEY * pkey, int op, long arg1, void *arg2) 642static int
643pkey_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
179int GOST_KEY_set_public_key_affine_coordinates(GOST_KEY * key, BIGNUM * x, BIGNUM * y) 179int
180GOST_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
136static int pkey_gost01_init(EVP_PKEY_CTX * ctx) 136static int
137pkey_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 */
154static int pkey_gost01_copy(EVP_PKEY_CTX * dst, EVP_PKEY_CTX * src) 156static int
157pkey_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 */
170static void pkey_gost01_cleanup(EVP_PKEY_CTX * ctx) 173static void
174pkey_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
177static int pkey_gost01_paramgen(EVP_PKEY_CTX * ctx, EVP_PKEY * pkey) 182static int
183pkey_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
212static int pkey_gost01_keygen(EVP_PKEY_CTX * ctx, EVP_PKEY * pkey) 219static int
220pkey_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
220static int pkey_gost01_sign(EVP_PKEY_CTX * ctx, unsigned char *sig, 227static int
221 size_t * siglen, const unsigned char *tbs, 228pkey_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
256static int pkey_gost01_verify(EVP_PKEY_CTX * ctx, const unsigned char *sig, 276static int
257 size_t siglen, const unsigned char *tbs, 277pkey_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
289static int gost01_VKO_key(EVP_PKEY * pub_key, EVP_PKEY * priv_key, 309static int
290 const unsigned char *ukm, unsigned char *key) 310gost01_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 }
359err:
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
335int pkey_gost01_decrypt(EVP_PKEY_CTX * pctx, unsigned char *key, 365int
336 size_t * key_len, const unsigned char *in, 366pkey_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: 429err:
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
406int pkey_gost01_derive(EVP_PKEY_CTX * ctx, unsigned char *key, 435int
407 size_t * keylen) 436pkey_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
432int pkey_gost01_encrypt(EVP_PKEY_CTX * pctx, unsigned char *out, 464int
433 size_t * out_len, const unsigned char *key, 465pkey_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) 557err:
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
522static int pkey_gost01_ctrl(EVP_PKEY_CTX * ctx, int type, int p1, void *p2) 565static int
566pkey_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 */