2 * Copyright 1995-2016 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
;
85 if (BN_cmp(dh
->g
, BN_value_one()) <= 0)
86 *ret
|= DH_NOT_SUITABLE_GENERATOR
;
87 else if (BN_cmp(dh
->g
, dh
->p
) >= 0)
88 *ret
|= DH_NOT_SUITABLE_GENERATOR
;
90 /* Check g^q == 1 mod p */
91 if (!BN_mod_exp(t1
, dh
->g
, dh
->q
, dh
->p
, ctx
))
94 *ret
|= DH_NOT_SUITABLE_GENERATOR
;
96 r
= BN_is_prime_ex(dh
->q
, BN_prime_checks
, ctx
, NULL
);
100 *ret
|= DH_CHECK_Q_NOT_PRIME
;
101 /* Check p == 1 mod q i.e. q divides p - 1 */
102 if (!BN_div(t1
, t2
, dh
->p
, dh
->q
, ctx
))
105 *ret
|= DH_CHECK_INVALID_Q_VALUE
;
106 if (dh
->j
&& BN_cmp(dh
->j
, t1
))
107 *ret
|= DH_CHECK_INVALID_J_VALUE
;
109 } else if (BN_is_word(dh
->g
, DH_GENERATOR_2
)) {
110 l
= BN_mod_word(dh
->p
, 24);
111 if (l
== (BN_ULONG
)-1)
114 *ret
|= DH_NOT_SUITABLE_GENERATOR
;
115 } else if (BN_is_word(dh
->g
, DH_GENERATOR_5
)) {
116 l
= BN_mod_word(dh
->p
, 10);
117 if (l
== (BN_ULONG
)-1)
119 if ((l
!= 3) && (l
!= 7))
120 *ret
|= DH_NOT_SUITABLE_GENERATOR
;
122 *ret
|= DH_UNABLE_TO_CHECK_GENERATOR
;
124 r
= BN_is_prime_ex(dh
->p
, BN_prime_checks
, ctx
, NULL
);
128 *ret
|= DH_CHECK_P_NOT_PRIME
;
130 if (!BN_rshift1(t1
, dh
->p
))
132 r
= BN_is_prime_ex(t1
, BN_prime_checks
, ctx
, NULL
);
136 *ret
|= DH_CHECK_P_NOT_SAFE_PRIME
;
147 int DH_check_pub_key(const DH
*dh
, const BIGNUM
*pub_key
, int *ret
)
158 tmp
= BN_CTX_get(ctx
);
159 if (tmp
== NULL
|| !BN_set_word(tmp
, 1))
161 if (BN_cmp(pub_key
, tmp
) <= 0)
162 *ret
|= DH_CHECK_PUBKEY_TOO_SMALL
;
163 if (BN_copy(tmp
, dh
->p
) == NULL
|| !BN_sub_word(tmp
, 1))
165 if (BN_cmp(pub_key
, tmp
) >= 0)
166 *ret
|= DH_CHECK_PUBKEY_TOO_LARGE
;
169 /* Check pub_key^q == 1 mod p */
170 if (!BN_mod_exp(tmp
, pub_key
, dh
->q
, dh
->p
, ctx
))
173 *ret
|= DH_CHECK_PUBKEY_INVALID
;