2 * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
11 #include "internal/cryptlib.h"
12 #include <openssl/bn.h>
16 * Check that p and g are suitable enough
22 int DH_check_params(const DH
*dh
, int *ret
)
33 tmp
= BN_CTX_get(ctx
);
37 if (!BN_is_odd(dh
->p
))
38 *ret
|= DH_CHECK_P_NOT_PRIME
;
39 if (BN_is_negative(dh
->g
) || BN_is_zero(dh
->g
) || BN_is_one(dh
->g
))
40 *ret
|= DH_NOT_SUITABLE_GENERATOR
;
41 if (BN_copy(tmp
, dh
->p
) == NULL
|| !BN_sub_word(tmp
, 1))
43 if (BN_cmp(dh
->g
, tmp
) >= 0)
44 *ret
|= DH_NOT_SUITABLE_GENERATOR
;
56 * Check that p is a safe prime and
57 * if g is 2, 3 or 5, check that it is a suitable generator
59 * for 2, p mod 24 == 11
60 * for 3, p mod 12 == 5
61 * for 5, p mod 10 == 3 or 7
65 int DH_check(const DH
*dh
, int *ret
)
70 BIGNUM
*t1
= NULL
, *t2
= NULL
;
83 if (BN_cmp(dh
->g
, BN_value_one()) <= 0)
84 *ret
|= DH_NOT_SUITABLE_GENERATOR
;
85 else if (BN_cmp(dh
->g
, dh
->p
) >= 0)
86 *ret
|= DH_NOT_SUITABLE_GENERATOR
;
88 /* Check g^q == 1 mod p */
89 if (!BN_mod_exp(t1
, dh
->g
, dh
->q
, dh
->p
, ctx
))
92 *ret
|= DH_NOT_SUITABLE_GENERATOR
;
94 r
= BN_is_prime_ex(dh
->q
, BN_prime_checks
, ctx
, NULL
);
98 *ret
|= DH_CHECK_Q_NOT_PRIME
;
99 /* Check p == 1 mod q i.e. q divides p - 1 */
100 if (!BN_div(t1
, t2
, dh
->p
, dh
->q
, ctx
))
103 *ret
|= DH_CHECK_INVALID_Q_VALUE
;
104 if (dh
->j
&& BN_cmp(dh
->j
, t1
))
105 *ret
|= DH_CHECK_INVALID_J_VALUE
;
107 } else if (BN_is_word(dh
->g
, DH_GENERATOR_2
)) {
108 l
= BN_mod_word(dh
->p
, 24);
109 if (l
== (BN_ULONG
)-1)
112 *ret
|= DH_NOT_SUITABLE_GENERATOR
;
113 } else if (BN_is_word(dh
->g
, DH_GENERATOR_5
)) {
114 l
= BN_mod_word(dh
->p
, 10);
115 if (l
== (BN_ULONG
)-1)
117 if ((l
!= 3) && (l
!= 7))
118 *ret
|= DH_NOT_SUITABLE_GENERATOR
;
120 *ret
|= DH_UNABLE_TO_CHECK_GENERATOR
;
122 r
= BN_is_prime_ex(dh
->p
, BN_prime_checks
, ctx
, NULL
);
126 *ret
|= DH_CHECK_P_NOT_PRIME
;
128 if (!BN_rshift1(t1
, dh
->p
))
130 r
= BN_is_prime_ex(t1
, BN_prime_checks
, ctx
, NULL
);
134 *ret
|= DH_CHECK_P_NOT_SAFE_PRIME
;
145 int DH_check_pub_key(const DH
*dh
, const BIGNUM
*pub_key
, int *ret
)
156 tmp
= BN_CTX_get(ctx
);
157 if (tmp
== NULL
|| !BN_set_word(tmp
, 1))
159 if (BN_cmp(pub_key
, tmp
) <= 0)
160 *ret
|= DH_CHECK_PUBKEY_TOO_SMALL
;
161 if (BN_copy(tmp
, dh
->p
) == NULL
|| !BN_sub_word(tmp
, 1))
163 if (BN_cmp(pub_key
, tmp
) >= 0)
164 *ret
|= DH_CHECK_PUBKEY_TOO_LARGE
;
167 /* Check pub_key^q == 1 mod p */
168 if (!BN_mod_exp(tmp
, pub_key
, dh
->q
, dh
->p
, ctx
))
171 *ret
|= DH_CHECK_PUBKEY_INVALID
;