summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2018-06-15 19:24:13 +0000
committertb <>2018-06-15 19:24:13 +0000
commita3ae248d6e35515f29a8a97a956d678a5cf9bb30 (patch)
tree9ca0ee6a1212018a6da9597acbb46e91aee4e22c
parent2c25c4b4c61884af3b090e7db459cc826945c359 (diff)
downloadopenbsd-a3ae248d6e35515f29a8a97a956d678a5cf9bb30.tar.gz
openbsd-a3ae248d6e35515f29a8a97a956d678a5cf9bb30.tar.bz2
openbsd-a3ae248d6e35515f29a8a97a956d678a5cf9bb30.zip
Basic cleanup. Handle the possibly NULL ctx_in in ecdsa_sign_setup() with
the usual idiom. All the allocations are now handled inside conditionals as is usually done in this part of the tree. Turn a few comments into actual sentences and remove a few self-evident ones. Change outdated or cryptic comments into more helpful annotations. In ecdsa_do_verify(), start calculating only after properly truncating the message digest. More consistent variable names: prefer 'order_bits' and 'point' over 'i' and 'tmp_point'. ok jsing
-rw-r--r--src/lib/libcrypto/ecdsa/ecs_ossl.c129
1 files changed, 62 insertions, 67 deletions
diff --git a/src/lib/libcrypto/ecdsa/ecs_ossl.c b/src/lib/libcrypto/ecdsa/ecs_ossl.c
index be279b34b6..eff2a5022d 100644
--- a/src/lib/libcrypto/ecdsa/ecs_ossl.c
+++ b/src/lib/libcrypto/ecdsa/ecs_ossl.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ecs_ossl.c,v 1.13 2018/06/15 05:00:41 tb Exp $ */ 1/* $OpenBSD: ecs_ossl.c,v 1.14 2018/06/15 19:24:13 tb Exp $ */
2/* 2/*
3 * Written by Nils Larsch for the OpenSSL project 3 * Written by Nils Larsch for the OpenSSL project
4 */ 4 */
@@ -88,9 +88,9 @@ ECDSA_OpenSSL(void)
88static int 88static int
89ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) 89ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
90{ 90{
91 BN_CTX *ctx = NULL; 91 BN_CTX *ctx = ctx_in;
92 BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL; 92 BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL;
93 EC_POINT *tmp_point = NULL; 93 EC_POINT *point = NULL;
94 const EC_GROUP *group; 94 const EC_GROUP *group;
95 int order_bits, ret = 0; 95 int order_bits, ret = 0;
96 96
@@ -99,23 +99,19 @@ ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
99 return 0; 99 return 0;
100 } 100 }
101 101
102 if (ctx_in == NULL) { 102 if (ctx == NULL) {
103 if ((ctx = BN_CTX_new()) == NULL) { 103 if ((ctx = BN_CTX_new()) == NULL) {
104 ECDSAerror(ERR_R_MALLOC_FAILURE); 104 ECDSAerror(ERR_R_MALLOC_FAILURE);
105 return 0; 105 return 0;
106 } 106 }
107 } else 107 }
108 ctx = ctx_in; 108
109 109 if ((k = BN_new()) == NULL || (r = BN_new()) == NULL ||
110 k = BN_new(); /* this value is later returned in *kinvp */ 110 (order = BN_new()) == NULL || (X = BN_new()) == NULL) {
111 r = BN_new(); /* this value is later returned in *rp */
112 order = BN_new();
113 X = BN_new();
114 if (!k || !r || !order || !X) {
115 ECDSAerror(ERR_R_MALLOC_FAILURE); 111 ECDSAerror(ERR_R_MALLOC_FAILURE);
116 goto err; 112 goto err;
117 } 113 }
118 if ((tmp_point = EC_POINT_new(group)) == NULL) { 114 if ((point = EC_POINT_new(group)) == NULL) {
119 ECDSAerror(ERR_R_EC_LIB); 115 ECDSAerror(ERR_R_EC_LIB);
120 goto err; 116 goto err;
121 } 117 }
@@ -132,14 +128,13 @@ ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
132 goto err; 128 goto err;
133 129
134 do { 130 do {
135 /* get random k */ 131 do {
136 do
137 if (!BN_rand_range(k, order)) { 132 if (!BN_rand_range(k, order)) {
138 ECDSAerror( 133 ECDSAerror(
139 ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED); 134 ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
140 goto err; 135 goto err;
141 } 136 }
142 while (BN_is_zero(k)); 137 } while (BN_is_zero(k));
143 138
144 /* 139 /*
145 * We do not want timing information to leak the length of k, 140 * We do not want timing information to leak the length of k,
@@ -162,23 +157,23 @@ ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
162 157
163 BN_set_flags(k, BN_FLG_CONSTTIME); 158 BN_set_flags(k, BN_FLG_CONSTTIME);
164 159
165 /* compute r the x-coordinate of generator * k */ 160 /* Compute r, the x-coordinate of G * k. */
166 if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) { 161 if (!EC_POINT_mul(group, point, k, NULL, NULL, ctx)) {
167 ECDSAerror(ERR_R_EC_LIB); 162 ECDSAerror(ERR_R_EC_LIB);
168 goto err; 163 goto err;
169 } 164 }
170 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == 165 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
171 NID_X9_62_prime_field) { 166 NID_X9_62_prime_field) {
172 if (!EC_POINT_get_affine_coordinates_GFp(group, 167 if (!EC_POINT_get_affine_coordinates_GFp(group, point,
173 tmp_point, X, NULL, ctx)) { 168 X, NULL, ctx)) {
174 ECDSAerror(ERR_R_EC_LIB); 169 ECDSAerror(ERR_R_EC_LIB);
175 goto err; 170 goto err;
176 } 171 }
177 } 172 }
178#ifndef OPENSSL_NO_EC2M 173#ifndef OPENSSL_NO_EC2M
179 else { /* NID_X9_62_characteristic_two_field */ 174 else { /* NID_X9_62_characteristic_two_field */
180 if (!EC_POINT_get_affine_coordinates_GF2m(group, 175 if (!EC_POINT_get_affine_coordinates_GF2m(group, point,
181 tmp_point, X, NULL, ctx)) { 176 X, NULL, ctx)) {
182 ECDSAerror(ERR_R_EC_LIB); 177 ECDSAerror(ERR_R_EC_LIB);
183 goto err; 178 goto err;
184 } 179 }
@@ -190,15 +185,12 @@ ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
190 } 185 }
191 } while (BN_is_zero(r)); 186 } while (BN_is_zero(r));
192 187
193 /* compute the inverse of k */
194 if (!BN_mod_inverse_ct(k, k, order, ctx)) { 188 if (!BN_mod_inverse_ct(k, k, order, ctx)) {
195 ECDSAerror(ERR_R_BN_LIB); 189 ECDSAerror(ERR_R_BN_LIB);
196 goto err; 190 goto err;
197 } 191 }
198 /* clear old values if necessary */
199 BN_clear_free(*rp); 192 BN_clear_free(*rp);
200 BN_clear_free(*kinvp); 193 BN_clear_free(*kinvp);
201 /* save the pre-computed values */
202 *rp = r; 194 *rp = r;
203 *kinvp = k; 195 *kinvp = k;
204 ret = 1; 196 ret = 1;
@@ -211,7 +203,7 @@ ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
211 if (ctx_in == NULL) 203 if (ctx_in == NULL)
212 BN_CTX_free(ctx); 204 BN_CTX_free(ctx);
213 BN_free(order); 205 BN_free(order);
214 EC_POINT_free(tmp_point); 206 EC_POINT_free(point);
215 BN_clear_free(X); 207 BN_clear_free(X);
216 return (ret); 208 return (ret);
217} 209}
@@ -228,7 +220,7 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
228 const EC_GROUP *group; 220 const EC_GROUP *group;
229 ECDSA_SIG *ret; 221 ECDSA_SIG *ret;
230 ECDSA_DATA *ecdsa; 222 ECDSA_DATA *ecdsa;
231 int ok = 0, i; 223 int ok = 0, order_bits;
232 224
233 ecdsa = ecdsa_check(eckey); 225 ecdsa = ecdsa_check(eckey);
234 group = EC_KEY_get0_group(eckey); 226 group = EC_KEY_get0_group(eckey);
@@ -239,8 +231,7 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
239 return NULL; 231 return NULL;
240 } 232 }
241 233
242 ret = ECDSA_SIG_new(); 234 if ((ret = ECDSA_SIG_new()) == NULL) {
243 if (!ret) {
244 ECDSAerror(ERR_R_MALLOC_FAILURE); 235 ECDSAerror(ERR_R_MALLOC_FAILURE);
245 return NULL; 236 return NULL;
246 } 237 }
@@ -258,18 +249,21 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
258 ECDSAerror(ERR_R_EC_LIB); 249 ECDSAerror(ERR_R_EC_LIB);
259 goto err; 250 goto err;
260 } 251 }
261 i = BN_num_bits(order); 252
262 /* Truncate digest if it is too long: first truncate whole bytes. */ 253 /* Truncate digest if it is too long: first truncate whole bytes. */
263 if (8 * dgst_len > i) 254 order_bits = BN_num_bits(order);
264 dgst_len = (i + 7)/8; 255 if (8 * dgst_len > order_bits)
256 dgst_len = (order_bits + 7) / 8;
265 if (!BN_bin2bn(dgst, dgst_len, m)) { 257 if (!BN_bin2bn(dgst, dgst_len, m)) {
266 ECDSAerror(ERR_R_BN_LIB); 258 ECDSAerror(ERR_R_BN_LIB);
267 goto err; 259 goto err;
268 } 260 }
269 /* If it is still too long, truncate the remaining bits with a shift. */ 261 /* If it is still too long, truncate the remaining bits with a shift. */
270 if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { 262 if (8 * dgst_len > order_bits) {
271 ECDSAerror(ERR_R_BN_LIB); 263 if (!BN_rshift(m, m, 8 - (order_bits & 0x7))) {
272 goto err; 264 ECDSAerror(ERR_R_BN_LIB);
265 goto err;
266 }
273 } 267 }
274 268
275 do { 269 do {
@@ -359,7 +353,7 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
359 ok = 1; 353 ok = 1;
360 354
361 err: 355 err:
362 if (!ok) { 356 if (ok == 0) {
363 ECDSA_SIG_free(ret); 357 ECDSA_SIG_free(ret);
364 ret = NULL; 358 ret = NULL;
365 } 359 }
@@ -379,22 +373,20 @@ static int
379ecdsa_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, 373ecdsa_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig,
380 EC_KEY *eckey) 374 EC_KEY *eckey)
381{ 375{
382 int ret = -1, i; 376 BN_CTX *ctx;
383 BN_CTX *ctx; 377 BIGNUM *order, *u1, *u2, *m, *X;
384 BIGNUM *order, *u1, *u2, *m, *X;
385 EC_POINT *point = NULL; 378 EC_POINT *point = NULL;
386 const EC_GROUP *group; 379 const EC_GROUP *group;
387 const EC_POINT *pub_key; 380 const EC_POINT *pub_key;
381 int order_bits, ret = -1;
388 382
389 /* check input values */
390 if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || 383 if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL ||
391 (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) { 384 (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) {
392 ECDSAerror(ECDSA_R_MISSING_PARAMETERS); 385 ECDSAerror(ECDSA_R_MISSING_PARAMETERS);
393 return -1; 386 return -1;
394 } 387 }
395 388
396 ctx = BN_CTX_new(); 389 if ((ctx = BN_CTX_new()) == NULL) {
397 if (!ctx) {
398 ECDSAerror(ERR_R_MALLOC_FAILURE); 390 ECDSAerror(ERR_R_MALLOC_FAILURE);
399 return -1; 391 return -1;
400 } 392 }
@@ -404,7 +396,7 @@ ecdsa_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig,
404 u2 = BN_CTX_get(ctx); 396 u2 = BN_CTX_get(ctx);
405 m = BN_CTX_get(ctx); 397 m = BN_CTX_get(ctx);
406 X = BN_CTX_get(ctx); 398 X = BN_CTX_get(ctx);
407 if (!X) { 399 if (X == NULL) {
408 ECDSAerror(ERR_R_BN_LIB); 400 ECDSAerror(ERR_R_BN_LIB);
409 goto err; 401 goto err;
410 } 402 }
@@ -414,43 +406,46 @@ ecdsa_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig,
414 goto err; 406 goto err;
415 } 407 }
416 408
417 if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || 409 /* Verify that r and s are in the range [1, order-1]. */
418 BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) || 410 if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
419 BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) { 411 BN_ucmp(sig->r, order) >= 0 ||
412 BN_is_zero(sig->s) || BN_is_negative(sig->s) ||
413 BN_ucmp(sig->s, order) >= 0) {
420 ECDSAerror(ECDSA_R_BAD_SIGNATURE); 414 ECDSAerror(ECDSA_R_BAD_SIGNATURE);
421 ret = 0; /* signature is invalid */ 415 ret = 0;
422 goto err;
423 }
424 /* calculate tmp1 = inv(S) mod order */
425 if (!BN_mod_inverse_ct(u2, sig->s, order, ctx)) {
426 ECDSAerror(ERR_R_BN_LIB);
427 goto err; 416 goto err;
428 } 417 }
429 /* digest -> m */ 418
430 i = BN_num_bits(order);
431 /* Truncate digest if it is too long: first truncate whole bytes. */ 419 /* Truncate digest if it is too long: first truncate whole bytes. */
432 if (8 * dgst_len > i) 420 order_bits = BN_num_bits(order);
433 dgst_len = (i + 7)/8; 421 if (8 * dgst_len > order_bits)
422 dgst_len = (order_bits + 7) / 8;
434 if (!BN_bin2bn(dgst, dgst_len, m)) { 423 if (!BN_bin2bn(dgst, dgst_len, m)) {
435 ECDSAerror(ERR_R_BN_LIB); 424 ECDSAerror(ERR_R_BN_LIB);
436 goto err; 425 goto err;
437 } 426 }
438 /* If it is still too long, truncate the remaining bits with a shift. */ 427 /* If it is still too long, truncate the remaining bits with a shift. */
439 if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { 428 if (8 * dgst_len > order_bits) {
429 if (!BN_rshift(m, m, 8 - (order_bits & 0x7))) {
430 ECDSAerror(ERR_R_BN_LIB);
431 goto err;
432 }
433 }
434
435 if (!BN_mod_inverse_ct(u2, sig->s, order, ctx)) { /* w = inv(s) */
440 ECDSAerror(ERR_R_BN_LIB); 436 ECDSAerror(ERR_R_BN_LIB);
441 goto err; 437 goto err;
442 } 438 }
443 /* u1 = m * tmp mod order */ 439 if (!BN_mod_mul(u1, m, u2, order, ctx)) { /* u1 = mw */
444 if (!BN_mod_mul(u1, m, u2, order, ctx)) {
445 ECDSAerror(ERR_R_BN_LIB); 440 ECDSAerror(ERR_R_BN_LIB);
446 goto err; 441 goto err;
447 } 442 }
448 /* u2 = r * w mod q */ 443 if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) { /* u2 = rw */
449 if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) {
450 ECDSAerror(ERR_R_BN_LIB); 444 ECDSAerror(ERR_R_BN_LIB);
451 goto err; 445 goto err;
452 } 446 }
453 447
448 /* Compute the x-coordinate of G * u1 + pub_key * u2. */
454 if ((point = EC_POINT_new(group)) == NULL) { 449 if ((point = EC_POINT_new(group)) == NULL) {
455 ECDSAerror(ERR_R_MALLOC_FAILURE); 450 ECDSAerror(ERR_R_MALLOC_FAILURE);
456 goto err; 451 goto err;
@@ -461,16 +456,16 @@ ecdsa_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig,
461 } 456 }
462 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == 457 if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) ==
463 NID_X9_62_prime_field) { 458 NID_X9_62_prime_field) {
464 if (!EC_POINT_get_affine_coordinates_GFp(group, 459 if (!EC_POINT_get_affine_coordinates_GFp(group, point, X, NULL,
465 point, X, NULL, ctx)) { 460 ctx)) {
466 ECDSAerror(ERR_R_EC_LIB); 461 ECDSAerror(ERR_R_EC_LIB);
467 goto err; 462 goto err;
468 } 463 }
469 } 464 }
470#ifndef OPENSSL_NO_EC2M 465#ifndef OPENSSL_NO_EC2M
471 else { /* NID_X9_62_characteristic_two_field */ 466 else { /* NID_X9_62_characteristic_two_field */
472 if (!EC_POINT_get_affine_coordinates_GF2m(group, 467 if (!EC_POINT_get_affine_coordinates_GF2m(group, point, X, NULL,
473 point, X, NULL, ctx)) { 468 ctx)) {
474 ECDSAerror(ERR_R_EC_LIB); 469 ECDSAerror(ERR_R_EC_LIB);
475 goto err; 470 goto err;
476 } 471 }
@@ -481,7 +476,7 @@ ecdsa_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig,
481 goto err; 476 goto err;
482 } 477 }
483 478
484 /* If the signature is correct, then u1 is equal to sig->r. */ 479 /* If the signature is correct, the x-coordinate is equal to sig->r. */
485 ret = (BN_ucmp(u1, sig->r) == 0); 480 ret = (BN_ucmp(u1, sig->r) == 0);
486 481
487 err: 482 err: