Coverage Report

Created: 2022-11-30 06:20

/src/openssl/crypto/dh/dh_check.c
Line
Count
Source (jump to first uncovered line)
1
/* crypto/dh/dh_check.c */
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 *
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 *
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 *
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 *
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 *
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
#include <stdio.h>
60
#include "cryptlib.h"
61
#include <openssl/bn.h>
62
#include <openssl/dh.h>
63
64
/*-
65
 * Check that p is a safe prime and
66
 * if g is 2, 3 or 5, check that it is a suitable generator
67
 * where
68
 * for 2, p mod 24 == 11
69
 * for 3, p mod 12 == 5
70
 * for 5, p mod 10 == 3 or 7
71
 * should hold.
72
 */
73
74
int DH_check(const DH *dh, int *ret)
75
0
{
76
0
    int ok = 0;
77
0
    BN_CTX *ctx = NULL;
78
0
    BN_ULONG l;
79
0
    BIGNUM *t1 = NULL, *t2 = NULL;
80
81
0
    *ret = 0;
82
0
    ctx = BN_CTX_new();
83
0
    if (ctx == NULL)
84
0
        goto err;
85
0
    BN_CTX_start(ctx);
86
0
    t1 = BN_CTX_get(ctx);
87
0
    if (t1 == NULL)
88
0
        goto err;
89
0
    t2 = BN_CTX_get(ctx);
90
0
    if (t2 == NULL)
91
0
        goto err;
92
93
0
    if (dh->q) {
94
0
        if (BN_cmp(dh->g, BN_value_one()) <= 0)
95
0
            *ret |= DH_NOT_SUITABLE_GENERATOR;
96
0
        else if (BN_cmp(dh->g, dh->p) >= 0)
97
0
            *ret |= DH_NOT_SUITABLE_GENERATOR;
98
0
        else {
99
            /* Check g^q == 1 mod p */
100
0
            if (!BN_mod_exp(t1, dh->g, dh->q, dh->p, ctx))
101
0
                goto err;
102
0
            if (!BN_is_one(t1))
103
0
                *ret |= DH_NOT_SUITABLE_GENERATOR;
104
0
        }
105
0
        if (!BN_is_prime_ex(dh->q, BN_prime_checks, ctx, NULL))
106
0
            *ret |= DH_CHECK_Q_NOT_PRIME;
107
        /* Check p == 1 mod q  i.e. q divides p - 1 */
108
0
        if (!BN_div(t1, t2, dh->p, dh->q, ctx))
109
0
            goto err;
110
0
        if (!BN_is_one(t2))
111
0
            *ret |= DH_CHECK_INVALID_Q_VALUE;
112
0
        if (dh->j && BN_cmp(dh->j, t1))
113
0
            *ret |= DH_CHECK_INVALID_J_VALUE;
114
115
0
    } else if (BN_is_word(dh->g, DH_GENERATOR_2)) {
116
0
        l = BN_mod_word(dh->p, 24);
117
0
        if (l != 11)
118
0
            *ret |= DH_NOT_SUITABLE_GENERATOR;
119
0
    }
120
#if 0
121
    else if (BN_is_word(dh->g, DH_GENERATOR_3)) {
122
        l = BN_mod_word(dh->p, 12);
123
        if (l != 5)
124
            *ret |= DH_NOT_SUITABLE_GENERATOR;
125
    }
126
#endif
127
0
    else if (BN_is_word(dh->g, DH_GENERATOR_5)) {
128
0
        l = BN_mod_word(dh->p, 10);
129
0
        if ((l != 3) && (l != 7))
130
0
            *ret |= DH_NOT_SUITABLE_GENERATOR;
131
0
    } else
132
0
        *ret |= DH_UNABLE_TO_CHECK_GENERATOR;
133
134
0
    if (!BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL))
135
0
        *ret |= DH_CHECK_P_NOT_PRIME;
136
0
    else if (!dh->q) {
137
0
        if (!BN_rshift1(t1, dh->p))
138
0
            goto err;
139
0
        if (!BN_is_prime_ex(t1, BN_prime_checks, ctx, NULL))
140
0
            *ret |= DH_CHECK_P_NOT_SAFE_PRIME;
141
0
    }
142
0
    ok = 1;
143
0
 err:
144
0
    if (ctx != NULL) {
145
0
        BN_CTX_end(ctx);
146
0
        BN_CTX_free(ctx);
147
0
    }
148
0
    return (ok);
149
0
}
150
151
int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
152
0
{
153
0
    int ok = 0;
154
0
    BIGNUM *tmp = NULL;
155
0
    BN_CTX *ctx = NULL;
156
157
0
    *ret = 0;
158
0
    ctx = BN_CTX_new();
159
0
    if (ctx == NULL)
160
0
        goto err;
161
0
    BN_CTX_start(ctx);
162
0
    tmp = BN_CTX_get(ctx);
163
0
    if (tmp == NULL || !BN_set_word(tmp, 1))
164
0
        goto err;
165
0
    if (BN_cmp(pub_key, tmp) <= 0)
166
0
        *ret |= DH_CHECK_PUBKEY_TOO_SMALL;
167
0
    if (BN_copy(tmp, dh->p) == NULL || !BN_sub_word(tmp, 1))
168
0
        goto err;
169
0
    if (BN_cmp(pub_key, tmp) >= 0)
170
0
        *ret |= DH_CHECK_PUBKEY_TOO_LARGE;
171
172
0
    if (dh->q != NULL) {
173
        /* Check pub_key^q == 1 mod p */
174
0
        if (!BN_mod_exp(tmp, pub_key, dh->q, dh->p, ctx))
175
0
            goto err;
176
0
        if (!BN_is_one(tmp))
177
0
            *ret |= DH_CHECK_PUBKEY_INVALID;
178
0
    }
179
180
0
    ok = 1;
181
0
 err:
182
0
    if (ctx != NULL) {
183
0
        BN_CTX_end(ctx);
184
0
        BN_CTX_free(ctx);
185
0
    }
186
0
    return (ok);
187
0
}