-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Backport DH_check from OpenSSL 1.1.0. #3375
Changes from 3 commits
a1fe1a0
8ed534d
9f62ba2
c558185
218744c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,7 +16,6 @@ | |
DH *DH_new(void); | ||
void DH_free(DH *); | ||
int DH_size(const DH *); | ||
int DH_check(const DH *, int *); | ||
int DH_check_pub_key(const DH *, const BIGNUM *, int *); | ||
int DH_generate_key(DH *); | ||
int DH_compute_key(unsigned char *, const BIGNUM *, DH *); | ||
|
@@ -34,6 +33,8 @@ | |
int DH_set0_pqg(DH *, BIGNUM *, BIGNUM *, BIGNUM *); | ||
void DH_get0_key(const DH *, const BIGNUM **, const BIGNUM **); | ||
int DH_set0_key(DH *, BIGNUM *, BIGNUM *); | ||
|
||
int Cryptography_DH_check(const DH *, int *); | ||
""" | ||
|
||
MACROS = """ | ||
|
@@ -114,4 +115,106 @@ | |
return 1; | ||
} | ||
#endif | ||
|
||
#if CRYPTOGRAPHY_OPENSSL_LESS_THAN_110 || defined(LIBRESSL_VERSION_NUMBER) | ||
# define DH_CHECK_Q_NOT_PRIME 0x10 | ||
# define DH_CHECK_INVALID_Q_VALUE 0x20 | ||
# define DH_CHECK_INVALID_J_VALUE 0x40 | ||
|
||
/*- | ||
* Check that p is a safe prime and | ||
* if g is 2, 3 or 5, check that it is a suitable generator | ||
* where | ||
* for 2, p mod 24 == 11 | ||
* for 3, p mod 12 == 5 | ||
* for 5, p mod 10 == 3 or 7 | ||
* should hold. | ||
*/ | ||
|
||
int Cryptography_DH_check(const DH *dh, int *ret) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For review purposes, is this from 1.1.0d? Could you add a comment stating what version it came from? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. GitHub says 1.1.0pre6 - not sure which letter release that is. How can I find out? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 1.1.0pre6 is itself a release number (it was the last pre-release prior to 1.1.0). So just add a comment saying it was updated to its current form in 1.1.0pre6 |
||
{ | ||
int ok = 0, r; | ||
BN_CTX *ctx = NULL; | ||
BN_ULONG l; | ||
BIGNUM *t1 = NULL, *t2 = NULL; | ||
|
||
*ret = 0; | ||
ctx = BN_CTX_new(); | ||
if (ctx == NULL) | ||
goto err; | ||
BN_CTX_start(ctx); | ||
t1 = BN_CTX_get(ctx); | ||
if (t1 == NULL) | ||
goto err; | ||
t2 = BN_CTX_get(ctx); | ||
if (t2 == NULL) | ||
goto err; | ||
|
||
if (dh->q) { | ||
if (BN_cmp(dh->g, BN_value_one()) <= 0) | ||
*ret |= DH_NOT_SUITABLE_GENERATOR; | ||
else if (BN_cmp(dh->g, dh->p) >= 0) | ||
*ret |= DH_NOT_SUITABLE_GENERATOR; | ||
else { | ||
/* Check g^q == 1 mod p */ | ||
if (!BN_mod_exp(t1, dh->g, dh->q, dh->p, ctx)) | ||
goto err; | ||
if (!BN_is_one(t1)) | ||
*ret |= DH_NOT_SUITABLE_GENERATOR; | ||
} | ||
r = BN_is_prime_ex(dh->q, BN_prime_checks, ctx, NULL); | ||
if (r < 0) | ||
goto err; | ||
if (!r) | ||
*ret |= DH_CHECK_Q_NOT_PRIME; | ||
/* Check p == 1 mod q i.e. q divides p - 1 */ | ||
if (!BN_div(t1, t2, dh->p, dh->q, ctx)) | ||
goto err; | ||
if (!BN_is_one(t2)) | ||
*ret |= DH_CHECK_INVALID_Q_VALUE; | ||
if (dh->j && BN_cmp(dh->j, t1)) | ||
*ret |= DH_CHECK_INVALID_J_VALUE; | ||
|
||
} else if (BN_is_word(dh->g, DH_GENERATOR_2)) { | ||
l = BN_mod_word(dh->p, 24); | ||
if (l == (BN_ULONG)-1) | ||
goto err; | ||
if (l != 11) | ||
*ret |= DH_NOT_SUITABLE_GENERATOR; | ||
} else if (BN_is_word(dh->g, DH_GENERATOR_5)) { | ||
l = BN_mod_word(dh->p, 10); | ||
if (l == (BN_ULONG)-1) | ||
goto err; | ||
if ((l != 3) && (l != 7)) | ||
*ret |= DH_NOT_SUITABLE_GENERATOR; | ||
} else | ||
*ret |= DH_UNABLE_TO_CHECK_GENERATOR; | ||
|
||
r = BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL); | ||
if (r < 0) | ||
goto err; | ||
if (!r) | ||
*ret |= DH_CHECK_P_NOT_PRIME; | ||
else if (!dh->q) { | ||
if (!BN_rshift1(t1, dh->p)) | ||
goto err; | ||
r = BN_is_prime_ex(t1, BN_prime_checks, ctx, NULL); | ||
if (r < 0) | ||
goto err; | ||
if (!r) | ||
*ret |= DH_CHECK_P_NOT_SAFE_PRIME; | ||
} | ||
ok = 1; | ||
err: | ||
if (ctx != NULL) { | ||
BN_CTX_end(ctx); | ||
BN_CTX_free(ctx); | ||
} | ||
return (ok); | ||
} | ||
#else | ||
int Cryptography_DH_check(const DH *dh, int *ret) { | ||
return DH_check(dh, ret); | ||
} | ||
#endif | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should each be ifndef for safety since we don't want to fail with duplicate definitions if/when LibreSSL adds these.