]>
Commit | Line | Data |
---|---|---|
aa6bb135 | 1 | /* |
edea42c6 | 2 | * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. |
d02b48c6 | 3 | * |
e38873f5 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
aa6bb135 RS |
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 | |
d02b48c6 RE |
8 | */ |
9 | ||
10 | #include <stdio.h> | |
b39fc560 | 11 | #include "internal/cryptlib.h" |
ec577822 | 12 | #include <openssl/bn.h> |
0aeddcfa | 13 | #include "dh_locl.h" |
d02b48c6 | 14 | |
26505153 RL |
15 | /*- |
16 | * Check that p and g are suitable enough | |
17 | * | |
18 | * p is odd | |
19 | * 1 < g < p - 1 | |
20 | */ | |
b0004708 PY |
21 | int DH_check_params_ex(const DH *dh) |
22 | { | |
23 | int errflags = 0; | |
24 | ||
25 | (void)DH_check_params(dh, &errflags); | |
26 | ||
27 | if ((errflags & DH_CHECK_P_NOT_PRIME) != 0) | |
28 | DHerr(DH_F_DH_CHECK_PARAMS_EX, DH_R_CHECK_P_NOT_PRIME); | |
29 | if ((errflags & DH_NOT_SUITABLE_GENERATOR) != 0) | |
30 | DHerr(DH_F_DH_CHECK_PARAMS_EX, DH_R_NOT_SUITABLE_GENERATOR); | |
31 | ||
32 | return errflags == 0; | |
33 | } | |
26505153 RL |
34 | |
35 | int DH_check_params(const DH *dh, int *ret) | |
36 | { | |
37 | int ok = 0; | |
38 | BIGNUM *tmp = NULL; | |
39 | BN_CTX *ctx = NULL; | |
40 | ||
41 | *ret = 0; | |
42 | ctx = BN_CTX_new(); | |
43 | if (ctx == NULL) | |
44 | goto err; | |
45 | BN_CTX_start(ctx); | |
46 | tmp = BN_CTX_get(ctx); | |
47 | if (tmp == NULL) | |
48 | goto err; | |
49 | ||
50 | if (!BN_is_odd(dh->p)) | |
51 | *ret |= DH_CHECK_P_NOT_PRIME; | |
52 | if (BN_is_negative(dh->g) || BN_is_zero(dh->g) || BN_is_one(dh->g)) | |
53 | *ret |= DH_NOT_SUITABLE_GENERATOR; | |
54 | if (BN_copy(tmp, dh->p) == NULL || !BN_sub_word(tmp, 1)) | |
55 | goto err; | |
56 | if (BN_cmp(dh->g, tmp) >= 0) | |
57 | *ret |= DH_NOT_SUITABLE_GENERATOR; | |
58 | ||
59 | ok = 1; | |
60 | err: | |
61 | if (ctx != NULL) { | |
62 | BN_CTX_end(ctx); | |
63 | BN_CTX_free(ctx); | |
64 | } | |
26a7d938 | 65 | return ok; |
26505153 RL |
66 | } |
67 | ||
1d97c843 TH |
68 | /*- |
69 | * Check that p is a safe prime and | |
5f0477f4 | 70 | * if g is 2, 3 or 5, check that it is a suitable generator |
d02b48c6 RE |
71 | * where |
72 | * for 2, p mod 24 == 11 | |
73 | * for 3, p mod 12 == 5 | |
74 | * for 5, p mod 10 == 3 or 7 | |
75 | * should hold. | |
76 | */ | |
b0004708 PY |
77 | int DH_check_ex(const DH *dh) |
78 | { | |
79 | int errflags = 0; | |
80 | ||
81 | (void)DH_check(dh, &errflags); | |
82 | ||
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); | |
97 | ||
98 | return errflags == 0; | |
99 | } | |
d02b48c6 | 100 | |
f971ccb2 | 101 | int DH_check(const DH *dh, int *ret) |
0f113f3e | 102 | { |
748e8530 | 103 | int ok = 0, r; |
0f113f3e MC |
104 | BN_CTX *ctx = NULL; |
105 | BN_ULONG l; | |
106 | BIGNUM *t1 = NULL, *t2 = NULL; | |
107 | ||
108 | *ret = 0; | |
109 | ctx = BN_CTX_new(); | |
110 | if (ctx == NULL) | |
111 | goto err; | |
112 | BN_CTX_start(ctx); | |
113 | t1 = BN_CTX_get(ctx); | |
0f113f3e MC |
114 | t2 = BN_CTX_get(ctx); |
115 | if (t2 == NULL) | |
116 | goto err; | |
d02b48c6 | 117 | |
0f113f3e MC |
118 | if (dh->q) { |
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; | |
123 | else { | |
124 | /* Check g^q == 1 mod p */ | |
125 | if (!BN_mod_exp(t1, dh->g, dh->q, dh->p, ctx)) | |
126 | goto err; | |
127 | if (!BN_is_one(t1)) | |
128 | *ret |= DH_NOT_SUITABLE_GENERATOR; | |
129 | } | |
748e8530 DB |
130 | r = BN_is_prime_ex(dh->q, BN_prime_checks, ctx, NULL); |
131 | if (r < 0) | |
132 | goto err; | |
133 | if (!r) | |
0f113f3e MC |
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)) | |
137 | goto err; | |
138 | if (!BN_is_one(t2)) | |
139 | *ret |= DH_CHECK_INVALID_Q_VALUE; | |
140 | if (dh->j && BN_cmp(dh->j, t1)) | |
141 | *ret |= DH_CHECK_INVALID_J_VALUE; | |
d02b48c6 | 142 | |
0f113f3e MC |
143 | } else if (BN_is_word(dh->g, DH_GENERATOR_2)) { |
144 | l = BN_mod_word(dh->p, 24); | |
d70a5627 DB |
145 | if (l == (BN_ULONG)-1) |
146 | goto err; | |
0f113f3e MC |
147 | if (l != 11) |
148 | *ret |= DH_NOT_SUITABLE_GENERATOR; | |
dfb56425 | 149 | } else if (BN_is_word(dh->g, DH_GENERATOR_5)) { |
0f113f3e | 150 | l = BN_mod_word(dh->p, 10); |
d70a5627 DB |
151 | if (l == (BN_ULONG)-1) |
152 | goto err; | |
0f113f3e MC |
153 | if ((l != 3) && (l != 7)) |
154 | *ret |= DH_NOT_SUITABLE_GENERATOR; | |
155 | } else | |
156 | *ret |= DH_UNABLE_TO_CHECK_GENERATOR; | |
d02b48c6 | 157 | |
748e8530 DB |
158 | r = BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL); |
159 | if (r < 0) | |
160 | goto err; | |
161 | if (!r) | |
0f113f3e MC |
162 | *ret |= DH_CHECK_P_NOT_PRIME; |
163 | else if (!dh->q) { | |
164 | if (!BN_rshift1(t1, dh->p)) | |
165 | goto err; | |
748e8530 DB |
166 | r = BN_is_prime_ex(t1, BN_prime_checks, ctx, NULL); |
167 | if (r < 0) | |
168 | goto err; | |
e705fcf1 | 169 | if (!r) |
0f113f3e MC |
170 | *ret |= DH_CHECK_P_NOT_SAFE_PRIME; |
171 | } | |
172 | ok = 1; | |
173 | err: | |
174 | if (ctx != NULL) { | |
175 | BN_CTX_end(ctx); | |
176 | BN_CTX_free(ctx); | |
177 | } | |
26a7d938 | 178 | return ok; |
0f113f3e | 179 | } |
bf3d6c0c | 180 | |
b0004708 PY |
181 | int DH_check_pub_key_ex(const DH *dh, const BIGNUM *pub_key) |
182 | { | |
183 | int errflags = 0; | |
184 | ||
185 | (void)DH_check(dh, &errflags); | |
186 | ||
187 | if ((errflags & DH_CHECK_PUBKEY_TOO_SMALL) != 0) | |
188 | DHerr(DH_F_DH_CHECK_PUB_KEY_EX, DH_R_CHECK_PUBKEY_TOO_SMALL); | |
189 | if ((errflags & DH_CHECK_PUBKEY_TOO_LARGE) != 0) | |
190 | DHerr(DH_F_DH_CHECK_PUB_KEY_EX, DH_R_CHECK_PUBKEY_TOO_LARGE); | |
191 | if ((errflags & DH_CHECK_PUBKEY_INVALID) != 0) | |
192 | DHerr(DH_F_DH_CHECK_PUB_KEY_EX, DH_R_CHECK_PUBKEY_INVALID); | |
193 | ||
194 | return errflags == 0; | |
195 | } | |
196 | ||
bf3d6c0c | 197 | int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) |
0f113f3e MC |
198 | { |
199 | int ok = 0; | |
b128abc3 MC |
200 | BIGNUM *tmp = NULL; |
201 | BN_CTX *ctx = NULL; | |
bf3d6c0c | 202 | |
0f113f3e | 203 | *ret = 0; |
b128abc3 MC |
204 | ctx = BN_CTX_new(); |
205 | if (ctx == NULL) | |
0f113f3e | 206 | goto err; |
b128abc3 MC |
207 | BN_CTX_start(ctx); |
208 | tmp = BN_CTX_get(ctx); | |
f5a12207 | 209 | if (tmp == NULL || !BN_set_word(tmp, 1)) |
b128abc3 | 210 | goto err; |
b128abc3 | 211 | if (BN_cmp(pub_key, tmp) <= 0) |
0f113f3e | 212 | *ret |= DH_CHECK_PUBKEY_TOO_SMALL; |
f5a12207 MC |
213 | if (BN_copy(tmp, dh->p) == NULL || !BN_sub_word(tmp, 1)) |
214 | goto err; | |
b128abc3 | 215 | if (BN_cmp(pub_key, tmp) >= 0) |
0f113f3e | 216 | *ret |= DH_CHECK_PUBKEY_TOO_LARGE; |
bf3d6c0c | 217 | |
b128abc3 MC |
218 | if (dh->q != NULL) { |
219 | /* Check pub_key^q == 1 mod p */ | |
220 | if (!BN_mod_exp(tmp, pub_key, dh->q, dh->p, ctx)) | |
221 | goto err; | |
222 | if (!BN_is_one(tmp)) | |
223 | *ret |= DH_CHECK_PUBKEY_INVALID; | |
224 | } | |
225 | ||
0f113f3e MC |
226 | ok = 1; |
227 | err: | |
b128abc3 MC |
228 | if (ctx != NULL) { |
229 | BN_CTX_end(ctx); | |
230 | BN_CTX_free(ctx); | |
231 | } | |
26a7d938 | 232 | return ok; |
0f113f3e | 233 | } |