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