check.c
Go to the documentation of this file.
1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young (eay@cryptsoft.com).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to. The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  * notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  * notice, this list of conditions and the following disclaimer in the
29  * documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  * must display the following acknowledgement:
32  * "This product includes cryptographic software written by
33  * Eric Young (eay@cryptsoft.com)"
34  * The word 'cryptographic' can be left out if the rouines from the library
35  * being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  * the apps directory (application code) you must include an acknowledgement:
38  * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed. i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.] */
56 
57 #include <openssl/dh.h>
58 
59 #include <openssl/bn.h>
60 
61 
62 int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *out_flags) {
63  *out_flags = 0;
64 
65  BN_CTX *ctx = BN_CTX_new();
66  if (ctx == NULL) {
67  return 0;
68  }
70 
71  int ok = 0;
72 
73  // Check |pub_key| is greater than 1.
75  if (tmp == NULL ||
76  !BN_set_word(tmp, 1)) {
77  goto err;
78  }
79  if (BN_cmp(pub_key, tmp) <= 0) {
80  *out_flags |= DH_CHECK_PUBKEY_TOO_SMALL;
81  }
82 
83  // Check |pub_key| is less than |dh->p| - 1.
84  if (!BN_copy(tmp, dh->p) ||
85  !BN_sub_word(tmp, 1)) {
86  goto err;
87  }
88  if (BN_cmp(pub_key, tmp) >= 0) {
89  *out_flags |= DH_CHECK_PUBKEY_TOO_LARGE;
90  }
91 
92  if (dh->q != NULL) {
93  // Check |pub_key|^|dh->q| is 1 mod |dh->p|. This is necessary for RFC 5114
94  // groups which are not safe primes but pick a generator on a prime-order
95  // subgroup of size |dh->q|.
96  if (!BN_mod_exp_mont(tmp, pub_key, dh->q, dh->p, ctx, NULL)) {
97  goto err;
98  }
99  if (!BN_is_one(tmp)) {
100  *out_flags |= DH_CHECK_PUBKEY_INVALID;
101  }
102  }
103 
104  ok = 1;
105 
106 err:
107  BN_CTX_end(ctx);
108  BN_CTX_free(ctx);
109  return ok;
110 }
111 
112 
113 int DH_check(const DH *dh, int *out_flags) {
114  // Check that p is a safe prime and if g is 2, 3 or 5, check that it is a
115  // suitable generator where:
116  // for 2, p mod 24 == 11
117  // for 3, p mod 12 == 5
118  // for 5, p mod 10 == 3 or 7
119  // should hold.
120  int ok = 0, r;
121  BN_CTX *ctx = NULL;
122  BN_ULONG l;
123  BIGNUM *t1 = NULL, *t2 = NULL;
124 
125  *out_flags = 0;
126  ctx = BN_CTX_new();
127  if (ctx == NULL) {
128  goto err;
129  }
130  BN_CTX_start(ctx);
131  t1 = BN_CTX_get(ctx);
132  if (t1 == NULL) {
133  goto err;
134  }
135  t2 = BN_CTX_get(ctx);
136  if (t2 == NULL) {
137  goto err;
138  }
139 
140  if (dh->q) {
141  if (BN_cmp(dh->g, BN_value_one()) <= 0) {
142  *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR;
143  } else if (BN_cmp(dh->g, dh->p) >= 0) {
144  *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR;
145  } else {
146  // Check g^q == 1 mod p
147  if (!BN_mod_exp_mont(t1, dh->g, dh->q, dh->p, ctx, NULL)) {
148  goto err;
149  }
150  if (!BN_is_one(t1)) {
151  *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR;
152  }
153  }
155  if (r < 0) {
156  goto err;
157  }
158  if (!r) {
159  *out_flags |= DH_CHECK_Q_NOT_PRIME;
160  }
161  // Check p == 1 mod q i.e. q divides p - 1
162  if (!BN_div(t1, t2, dh->p, dh->q, ctx)) {
163  goto err;
164  }
165  if (!BN_is_one(t2)) {
166  *out_flags |= DH_CHECK_INVALID_Q_VALUE;
167  }
168  if (dh->j && BN_cmp(dh->j, t1)) {
169  *out_flags |= DH_CHECK_INVALID_J_VALUE;
170  }
171  } else if (BN_is_word(dh->g, DH_GENERATOR_2)) {
172  l = BN_mod_word(dh->p, 24);
173  if (l == (BN_ULONG)-1) {
174  goto err;
175  }
176  if (l != 11) {
177  *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR;
178  }
179  } else if (BN_is_word(dh->g, DH_GENERATOR_5)) {
180  l = BN_mod_word(dh->p, 10);
181  if (l == (BN_ULONG)-1) {
182  goto err;
183  }
184  if (l != 3 && l != 7) {
185  *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR;
186  }
187  } else {
189  }
190 
192  if (r < 0) {
193  goto err;
194  }
195  if (!r) {
196  *out_flags |= DH_CHECK_P_NOT_PRIME;
197  } else if (!dh->q) {
198  if (!BN_rshift1(t1, dh->p)) {
199  goto err;
200  }
202  if (r < 0) {
203  goto err;
204  }
205  if (!r) {
206  *out_flags |= DH_CHECK_P_NOT_SAFE_PRIME;
207  }
208  }
209  ok = 1;
210 
211 err:
212  if (ctx != NULL) {
213  BN_CTX_end(ctx);
214  BN_CTX_free(ctx);
215  }
216  return ok;
217 }
bn.h
BN_rshift1
#define BN_rshift1
Definition: boringssl_prefix_symbols.h:988
ctx
Definition: benchmark-async.c:30
DH_CHECK_INVALID_J_VALUE
#define DH_CHECK_INVALID_J_VALUE
Definition: dh.h:219
DH_CHECK_P_NOT_SAFE_PRIME
#define DH_CHECK_P_NOT_SAFE_PRIME
Definition: dh.h:214
error_ref_leak.err
err
Definition: error_ref_leak.py:35
DH_CHECK_Q_NOT_PRIME
#define DH_CHECK_Q_NOT_PRIME
Definition: dh.h:217
bignum_ctx
Definition: ctx.c:91
BN_CTX_get
#define BN_CTX_get
Definition: boringssl_prefix_symbols.h:884
DH_CHECK_PUBKEY_TOO_SMALL
#define DH_CHECK_PUBKEY_TOO_SMALL
Definition: dh.h:232
BN_set_word
#define BN_set_word
Definition: boringssl_prefix_symbols.h:992
BN_value_one
const OPENSSL_EXPORT BIGNUM * BN_value_one(void)
DH_CHECK_NOT_SUITABLE_GENERATOR
#define DH_CHECK_NOT_SUITABLE_GENERATOR
Definition: dh.h:216
DH_CHECK_UNABLE_TO_CHECK_GENERATOR
#define DH_CHECK_UNABLE_TO_CHECK_GENERATOR
Definition: dh.h:215
dh.h
dh_st::q
BIGNUM * q
Definition: dh.h:319
BN_mod_exp_mont
#define BN_mod_exp_mont
Definition: boringssl_prefix_symbols.h:950
DH_CHECK_PUBKEY_INVALID
#define DH_CHECK_PUBKEY_INVALID
Definition: dh.h:234
BN_sub_word
#define BN_sub_word
Definition: boringssl_prefix_symbols.h:996
BN_is_word
#define BN_is_word
Definition: boringssl_prefix_symbols.h:939
BN_CTX_new
#define BN_CTX_new
Definition: boringssl_prefix_symbols.h:885
BN_mod_word
#define BN_mod_word
Definition: boringssl_prefix_symbols.h:967
dh_st::g
BIGNUM * g
Definition: dh.h:307
DH_CHECK_P_NOT_PRIME
#define DH_CHECK_P_NOT_PRIME
Definition: dh.h:213
BN_copy
#define BN_copy
Definition: boringssl_prefix_symbols.h:914
DH_CHECK_PUBKEY_TOO_LARGE
#define DH_CHECK_PUBKEY_TOO_LARGE
Definition: dh.h:233
DH_GENERATOR_2
#define DH_GENERATOR_2
Definition: dh.h:150
BN_CTX_start
#define BN_CTX_start
Definition: boringssl_prefix_symbols.h:886
DH_CHECK_INVALID_Q_VALUE
#define DH_CHECK_INVALID_Q_VALUE
Definition: dh.h:218
bignum_st
Definition: bn.h:957
BN_is_one
#define BN_is_one
Definition: boringssl_prefix_symbols.h:935
BN_CTX_free
#define BN_CTX_free
Definition: boringssl_prefix_symbols.h:883
fix_build_deps.r
r
Definition: fix_build_deps.py:491
BN_cmp
#define BN_cmp
Definition: boringssl_prefix_symbols.h:912
ok
bool ok
Definition: async_end2end_test.cc:197
DH_GENERATOR_5
#define DH_GENERATOR_5
Definition: dh.h:151
BN_is_prime_ex
#define BN_is_prime_ex
Definition: boringssl_prefix_symbols.h:937
dh_st::p
BIGNUM * p
Definition: dh.h:306
dh_st::j
BIGNUM * j
Definition: dh.h:320
BN_CTX_end
#define BN_CTX_end
Definition: boringssl_prefix_symbols.h:882
dh_st
Definition: dh.h:305
DH_check_pub_key
int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *out_flags)
Definition: check.c:62
autogen_x86imm.tmp
tmp
Definition: autogen_x86imm.py:12
run_grpclb_interop_tests.l
dictionary l
Definition: run_grpclb_interop_tests.py:410
t1
Table t1
Definition: abseil-cpp/absl/container/internal/raw_hash_set_allocator_test.cc:185
DH_check
int DH_check(const DH *dh, int *out_flags)
Definition: check.c:113
BN_div
#define BN_div
Definition: boringssl_prefix_symbols.h:917
BN_prime_checks_for_validation
#define BN_prime_checks_for_validation
Definition: bn.h:692


grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:58:44