diff options
author | tb <> | 2018-07-10 21:36:02 +0000 |
---|---|---|
committer | tb <> | 2018-07-10 21:36:02 +0000 |
commit | 3e9d63e141c20976d81cba82a0f22542653c2d5a (patch) | |
tree | 674ee1900f746309089e0148270b77f115c4cb19 | |
parent | 5f464aed510641e01dcc51e32f8df5451d6e9022 (diff) | |
download | openbsd-3e9d63e141c20976d81cba82a0f22542653c2d5a.tar.gz openbsd-3e9d63e141c20976d81cba82a0f22542653c2d5a.tar.bz2 openbsd-3e9d63e141c20976d81cba82a0f22542653c2d5a.zip |
Factor out a bit of ugly code that truncates the digest to the order_bits
leftmost bits of a longer digest, according to FIPS 183-6, 6.4. Eliminate
a microoptimization that only converts the relevant part of the digest to
a bignum.
ok beck, jsing
-rw-r--r-- | src/lib/libcrypto/ecdsa/ecs_ossl.c | 64 |
1 files changed, 32 insertions, 32 deletions
diff --git a/src/lib/libcrypto/ecdsa/ecs_ossl.c b/src/lib/libcrypto/ecdsa/ecs_ossl.c index 720fa1f741..87d80642df 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.15 2018/06/16 08:11:33 tb Exp $ */ | 1 | /* $OpenBSD: ecs_ossl.c,v 1.16 2018/07/10 21:36:02 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Written by Nils Larsch for the OpenSSL project | 3 | * Written by Nils Larsch for the OpenSSL project |
4 | */ | 4 | */ |
@@ -65,7 +65,9 @@ | |||
65 | #include "bn_lcl.h" | 65 | #include "bn_lcl.h" |
66 | #include "ecs_locl.h" | 66 | #include "ecs_locl.h" |
67 | 67 | ||
68 | static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen, | 68 | static int ecdsa_prepare_digest(const unsigned char *dgst, int dgst_len, |
69 | BIGNUM *order, BIGNUM *ret); | ||
70 | static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, | ||
69 | const BIGNUM *, const BIGNUM *, EC_KEY *eckey); | 71 | const BIGNUM *, const BIGNUM *, EC_KEY *eckey); |
70 | static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, | 72 | static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, |
71 | BIGNUM **rp); | 73 | BIGNUM **rp); |
@@ -86,6 +88,30 @@ ECDSA_OpenSSL(void) | |||
86 | } | 88 | } |
87 | 89 | ||
88 | static int | 90 | static int |
91 | ecdsa_prepare_digest(const unsigned char *dgst, int dgst_len, BIGNUM *order, | ||
92 | BIGNUM *ret) | ||
93 | { | ||
94 | int dgst_bits, order_bits; | ||
95 | |||
96 | if (!BN_bin2bn(dgst, dgst_len, ret)) { | ||
97 | ECDSAerror(ERR_R_BN_LIB); | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | /* FIPS 186-3 6.4: Use order_bits leftmost bits if digest is too long */ | ||
102 | dgst_bits = 8 * dgst_len; | ||
103 | order_bits = BN_num_bits(order); | ||
104 | if (dgst_bits > order_bits) { | ||
105 | if (!BN_rshift(ret, ret, dgst_bits - order_bits)) { | ||
106 | ECDSAerror(ERR_R_BN_LIB); | ||
107 | return 0; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | return 1; | ||
112 | } | ||
113 | |||
114 | static int | ||
89 | ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) | 115 | ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) |
90 | { | 116 | { |
91 | BN_CTX *ctx = ctx_in; | 117 | BN_CTX *ctx = ctx_in; |
@@ -220,7 +246,7 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, | |||
220 | const EC_GROUP *group; | 246 | const EC_GROUP *group; |
221 | ECDSA_SIG *ret; | 247 | ECDSA_SIG *ret; |
222 | ECDSA_DATA *ecdsa; | 248 | ECDSA_DATA *ecdsa; |
223 | int ok = 0, order_bits; | 249 | int ok = 0; |
224 | 250 | ||
225 | ecdsa = ecdsa_check(eckey); | 251 | ecdsa = ecdsa_check(eckey); |
226 | group = EC_KEY_get0_group(eckey); | 252 | group = EC_KEY_get0_group(eckey); |
@@ -250,21 +276,8 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, | |||
250 | goto err; | 276 | goto err; |
251 | } | 277 | } |
252 | 278 | ||
253 | /* Truncate digest if it is too long: first truncate whole bytes. */ | 279 | if (!ecdsa_prepare_digest(dgst, dgst_len, order, m)) |
254 | order_bits = BN_num_bits(order); | ||
255 | if (8 * dgst_len > order_bits) | ||
256 | dgst_len = (order_bits + 7) / 8; | ||
257 | if (!BN_bin2bn(dgst, dgst_len, m)) { | ||
258 | ECDSAerror(ERR_R_BN_LIB); | ||
259 | goto err; | 280 | goto err; |
260 | } | ||
261 | /* If it is still too long, truncate the remaining bits with a shift. */ | ||
262 | if (8 * dgst_len > order_bits) { | ||
263 | if (!BN_rshift(m, m, 8 - (order_bits & 0x7))) { | ||
264 | ECDSAerror(ERR_R_BN_LIB); | ||
265 | goto err; | ||
266 | } | ||
267 | } | ||
268 | 281 | ||
269 | do { | 282 | do { |
270 | if (in_kinv == NULL || in_r == NULL) { | 283 | if (in_kinv == NULL || in_r == NULL) { |
@@ -380,7 +393,7 @@ ecdsa_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, | |||
380 | EC_POINT *point = NULL; | 393 | EC_POINT *point = NULL; |
381 | const EC_GROUP *group; | 394 | const EC_GROUP *group; |
382 | const EC_POINT *pub_key; | 395 | const EC_POINT *pub_key; |
383 | int order_bits, ret = -1; | 396 | int ret = -1; |
384 | 397 | ||
385 | if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || | 398 | if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || |
386 | (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) { | 399 | (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) { |
@@ -418,21 +431,8 @@ ecdsa_do_verify(const unsigned char *dgst, int dgst_len, const ECDSA_SIG *sig, | |||
418 | goto err; | 431 | goto err; |
419 | } | 432 | } |
420 | 433 | ||
421 | /* Truncate digest if it is too long: first truncate whole bytes. */ | 434 | if (!ecdsa_prepare_digest(dgst, dgst_len, order, m)) |
422 | order_bits = BN_num_bits(order); | ||
423 | if (8 * dgst_len > order_bits) | ||
424 | dgst_len = (order_bits + 7) / 8; | ||
425 | if (!BN_bin2bn(dgst, dgst_len, m)) { | ||
426 | ECDSAerror(ERR_R_BN_LIB); | ||
427 | goto err; | 435 | goto err; |
428 | } | ||
429 | /* If it is still too long, truncate the remaining bits with a shift. */ | ||
430 | if (8 * dgst_len > order_bits) { | ||
431 | if (!BN_rshift(m, m, 8 - (order_bits & 0x7))) { | ||
432 | ECDSAerror(ERR_R_BN_LIB); | ||
433 | goto err; | ||
434 | } | ||
435 | } | ||
436 | 436 | ||
437 | if (!BN_mod_inverse_ct(u2, sig->s, order, ctx)) { /* w = inv(s) */ | 437 | if (!BN_mod_inverse_ct(u2, sig->s, order, ctx)) { /* w = inv(s) */ |
438 | ECDSAerror(ERR_R_BN_LIB); | 438 | ECDSAerror(ERR_R_BN_LIB); |