2 * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (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>
15 # define DH_NUMBER_ITERATIONS_FOR_PRIME 64
18 * Check that p and g are suitable enough
23 int DH_check_params_ex(const DH
*dh
)
27 (void)DH_check_params(dh
, &errflags
);
29 if ((errflags
& DH_CHECK_P_NOT_PRIME
) != 0)
30 DHerr(DH_F_DH_CHECK_PARAMS_EX
, DH_R_CHECK_P_NOT_PRIME
);
31 if ((errflags
& DH_NOT_SUITABLE_GENERATOR
) != 0)
32 DHerr(DH_F_DH_CHECK_PARAMS_EX
, DH_R_NOT_SUITABLE_GENERATOR
);
37 int DH_check_params(const DH
*dh
, int *ret
)
48 tmp
= BN_CTX_get(ctx
);
52 if (!BN_is_odd(dh
->p
))
53 *ret
|= DH_CHECK_P_NOT_PRIME
;
54 if (BN_is_negative(dh
->g
) || BN_is_zero(dh
->g
) || BN_is_one(dh
->g
))
55 *ret
|= DH_NOT_SUITABLE_GENERATOR
;
56 if (BN_copy(tmp
, dh
->p
) == NULL
|| !BN_sub_word(tmp
, 1))
58 if (BN_cmp(dh
->g
, tmp
) >= 0)
59 *ret
|= DH_NOT_SUITABLE_GENERATOR
;
69 * Check that p is a safe prime and
70 * if g is 2, 3 or 5, check that it is a suitable generator
72 * for 2, p mod 24 == 11
73 * for 3, p mod 12 == 5
74 * for 5, p mod 10 == 3 or 7
77 int DH_check_ex(const DH
*dh
)
81 (void)DH_check(dh
, &errflags
);
83 if ((errflags
& DH_NOT_SUITABLE_GENERATOR
) != 0)
84 DHerr(DH_F_DH_CHECK_EX
, DH_R_NOT_SUITABLE_GENERATOR
);
85 if ((errflags
& DH_CHECK_Q_NOT_PRIME
) != 0)
86 DHerr(DH_F_DH_CHECK_EX
, DH_R_CHECK_Q_NOT_PRIME
);
87 if ((errflags
& DH_CHECK_INVALID_Q_VALUE
) != 0)
88 DHerr(DH_F_DH_CHECK_EX
, DH_R_CHECK_INVALID_Q_VALUE
);
89 if ((errflags
& DH_CHECK_INVALID_J_VALUE
) != 0)
90 DHerr(DH_F_DH_CHECK_EX
, DH_R_CHECK_INVALID_J_VALUE
);
91 if ((errflags
& DH_UNABLE_TO_CHECK_GENERATOR
) != 0)
92 DHerr(DH_F_DH_CHECK_EX
, DH_R_UNABLE_TO_CHECK_GENERATOR
);
93 if ((errflags
& DH_CHECK_P_NOT_PRIME
) != 0)
94 DHerr(DH_F_DH_CHECK_EX
, DH_R_CHECK_P_NOT_PRIME
);
95 if ((errflags
& DH_CHECK_P_NOT_SAFE_PRIME
) != 0)
96 DHerr(DH_F_DH_CHECK_EX
, DH_R_CHECK_P_NOT_SAFE_PRIME
);
101 int DH_check(const DH
*dh
, int *ret
)
106 BIGNUM
*t1
= NULL
, *t2
= NULL
;
113 t1
= BN_CTX_get(ctx
);
114 t2
= BN_CTX_get(ctx
);
119 if (BN_cmp(dh
->g
, BN_value_one()) <= 0)
120 *ret
|= DH_NOT_SUITABLE_GENERATOR
;
121 else if (BN_cmp(dh
->g
, dh
->p
) >= 0)
122 *ret
|= DH_NOT_SUITABLE_GENERATOR
;
124 /* Check g^q == 1 mod p */
125 if (!BN_mod_exp(t1
, dh
->g
, dh
->q
, dh
->p
, ctx
))
128 *ret
|= DH_NOT_SUITABLE_GENERATOR
;
130 r
= BN_is_prime_ex(dh
->q
, DH_NUMBER_ITERATIONS_FOR_PRIME
, ctx
, NULL
);
134 *ret
|= DH_CHECK_Q_NOT_PRIME
;
135 /* Check p == 1 mod q i.e. q divides p - 1 */
136 if (!BN_div(t1
, t2
, dh
->p
, dh
->q
, ctx
))
139 *ret
|= DH_CHECK_INVALID_Q_VALUE
;
140 if (dh
->j
&& BN_cmp(dh
->j
, t1
))
141 *ret
|= DH_CHECK_INVALID_J_VALUE
;
143 } else if (BN_is_word(dh
->g
, DH_GENERATOR_2
)) {
144 l
= BN_mod_word(dh
->p
, 24);
145 if (l
== (BN_ULONG
)-1)
148 *ret
|= DH_NOT_SUITABLE_GENERATOR
;
149 } else if (BN_is_word(dh
->g
, DH_GENERATOR_5
)) {
150 l
= BN_mod_word(dh
->p
, 10);
151 if (l
== (BN_ULONG
)-1)
153 if ((l
!= 3) && (l
!= 7))
154 *ret
|= DH_NOT_SUITABLE_GENERATOR
;
156 *ret
|= DH_UNABLE_TO_CHECK_GENERATOR
;
158 r
= BN_is_prime_ex(dh
->p
, DH_NUMBER_ITERATIONS_FOR_PRIME
, ctx
, NULL
);
162 *ret
|= DH_CHECK_P_NOT_PRIME
;
164 if (!BN_rshift1(t1
, dh
->p
))
166 r
= BN_is_prime_ex(t1
, DH_NUMBER_ITERATIONS_FOR_PRIME
, ctx
, NULL
);
170 *ret
|= DH_CHECK_P_NOT_SAFE_PRIME
;
179 int DH_check_pub_key_ex(const DH
*dh
, const BIGNUM
*pub_key
)
183 (void)DH_check(dh
, &errflags
);
185 if ((errflags
& DH_CHECK_PUBKEY_TOO_SMALL
) != 0)
186 DHerr(DH_F_DH_CHECK_PUB_KEY_EX
, DH_R_CHECK_PUBKEY_TOO_SMALL
);
187 if ((errflags
& DH_CHECK_PUBKEY_TOO_LARGE
) != 0)
188 DHerr(DH_F_DH_CHECK_PUB_KEY_EX
, DH_R_CHECK_PUBKEY_TOO_LARGE
);
189 if ((errflags
& DH_CHECK_PUBKEY_INVALID
) != 0)
190 DHerr(DH_F_DH_CHECK_PUB_KEY_EX
, DH_R_CHECK_PUBKEY_INVALID
);
192 return errflags
== 0;
195 int DH_check_pub_key(const DH
*dh
, const BIGNUM
*pub_key
, int *ret
)
206 tmp
= BN_CTX_get(ctx
);
207 if (tmp
== NULL
|| !BN_set_word(tmp
, 1))
209 if (BN_cmp(pub_key
, tmp
) <= 0)
210 *ret
|= DH_CHECK_PUBKEY_TOO_SMALL
;
211 if (BN_copy(tmp
, dh
->p
) == NULL
|| !BN_sub_word(tmp
, 1))
213 if (BN_cmp(pub_key
, tmp
) >= 0)
214 *ret
|= DH_CHECK_PUBKEY_TOO_LARGE
;
217 /* Check pub_key^q == 1 mod p */
218 if (!BN_mod_exp(tmp
, pub_key
, dh
->q
, dh
->p
, ctx
))
221 *ret
|= DH_CHECK_PUBKEY_INVALID
;