diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libcrypto/dh/dh_check.c | 71 |
1 files changed, 53 insertions, 18 deletions
diff --git a/src/lib/libcrypto/dh/dh_check.c b/src/lib/libcrypto/dh/dh_check.c index b06e971235..7b9fcbdf5a 100644 --- a/src/lib/libcrypto/dh/dh_check.c +++ b/src/lib/libcrypto/dh/dh_check.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: dh_check.c,v 1.20 2021/11/29 19:54:07 tb Exp $ */ | 1 | /* $OpenBSD: dh_check.c,v 1.21 2021/11/29 20:02:14 tb Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -187,22 +187,57 @@ DH_check(const DH *dh, int *flags) | |||
187 | } | 187 | } |
188 | 188 | ||
189 | int | 189 | int |
190 | DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) | 190 | DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *flags) |
191 | { | 191 | { |
192 | BIGNUM *q = NULL; | 192 | BN_CTX *ctx = NULL; |
193 | 193 | BIGNUM *max_pub_key; | |
194 | *ret = 0; | 194 | int ok = 0; |
195 | q = BN_new(); | 195 | |
196 | if (q == NULL) | 196 | *flags = 0; |
197 | return 0; | 197 | |
198 | BN_set_word(q, 1); | 198 | if ((ctx = BN_CTX_new()) == NULL) |
199 | if (BN_cmp(pub_key, q) <= 0) | 199 | goto err; |
200 | *ret |= DH_CHECK_PUBKEY_TOO_SMALL; | 200 | BN_CTX_start(ctx); |
201 | BN_copy(q, dh->p); | 201 | if ((max_pub_key = BN_CTX_get(ctx)) == NULL) |
202 | BN_sub_word(q, 1); | 202 | goto err; |
203 | if (BN_cmp(pub_key, q) >= 0) | 203 | |
204 | *ret |= DH_CHECK_PUBKEY_TOO_LARGE; | 204 | /* |
205 | 205 | * Check that 1 < pub_key < dh->p - 1 | |
206 | BN_free(q); | 206 | */ |
207 | return 1; | 207 | |
208 | if (BN_cmp(pub_key, BN_value_one()) <= 0) | ||
209 | *flags |= DH_CHECK_PUBKEY_TOO_SMALL; | ||
210 | |||
211 | /* max_pub_key = dh->p - 1 */ | ||
212 | if (BN_copy(max_pub_key, dh->p) == NULL) | ||
213 | goto err; | ||
214 | if (!BN_sub_word(max_pub_key, 1)) | ||
215 | goto err; | ||
216 | |||
217 | if (BN_cmp(pub_key, max_pub_key) >= 0) | ||
218 | *flags |= DH_CHECK_PUBKEY_TOO_LARGE; | ||
219 | |||
220 | /* | ||
221 | * If dh->q is set, check that pub_key^q == 1 mod p | ||
222 | */ | ||
223 | |||
224 | if (dh->q != NULL) { | ||
225 | BIGNUM *residue; | ||
226 | |||
227 | if ((residue = BN_CTX_get(ctx)) == NULL) | ||
228 | goto err; | ||
229 | |||
230 | if (!BN_mod_exp_ct(residue, pub_key, dh->q, dh->p, ctx)) | ||
231 | goto err; | ||
232 | if (!BN_is_one(residue)) | ||
233 | *flags = DH_CHECK_PUBKEY_INVALID; | ||
234 | } | ||
235 | |||
236 | ok = 1; | ||
237 | |||
238 | err: | ||
239 | BN_CTX_end(ctx); | ||
240 | BN_CTX_free(ctx); | ||
241 | |||
242 | return ok; | ||
208 | } | 243 | } |