summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormiod <>2014-11-13 20:29:55 +0000
committermiod <>2014-11-13 20:29:55 +0000
commitda465ded4cecf3a87400ac2969ac59685296eac2 (patch)
tree28678f3b243e8187a88fe1d940c49b3c37443f67 /src
parent89f79a1eedd8ac48c7243143f774e2e2e0d47fe2 (diff)
downloadopenbsd-da465ded4cecf3a87400ac2969ac59685296eac2.tar.gz
openbsd-da465ded4cecf3a87400ac2969ac59685296eac2.tar.bz2
openbsd-da465ded4cecf3a87400ac2969ac59685296eac2.zip
Add many missing error checks (probably not exhaustive, but a good start):
- make VKO_compute_key() no longer void so that it can return failure. - fix unchecked allocations in too many routines to mention /-: - fix unchecked BN operations in gost2001_do_sign(), gost2001_do_verify(), VKO_compute_key(). - fix the gost2001_do_sign() interface violation by having its sole caller free the BIGNUM it passes to that function by itself, instead of having the callee do this. Reviewed (except for the last item) by Dmitry Eremin-Solenikov.
Diffstat (limited to 'src')
-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 */