1139799Simp/* crypto/dh/dh_check.c */
211397Sswallace/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
311397Sswallace * All rights reserved.
43584Ssos *
53584Ssos * This package is an SSL implementation written
63584Ssos * by Eric Young (eay@cryptsoft.com).
73584Ssos * The implementation was written so as to conform with Netscapes SSL.
83584Ssos *
93584Ssos * This library is free for commercial and non-commercial use as long as
1011397Sswallace * the following conditions are aheared to.  The following conditions
1111397Sswallace * apply to all code found in this distribution, be it the RC4, RSA,
1211397Sswallace * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
133584Ssos * included with this distribution is covered by the same copyright terms
143584Ssos * except that the holder is Tim Hudson (tjh@cryptsoft.com).
153584Ssos *
163584Ssos * Copyright remains Eric Young's, and as such any Copyright notices in
173584Ssos * the code are not to be removed.
183584Ssos * If this package is used in a product, Eric Young should be given attribution
193584Ssos * as the author of the parts of the library used.
203584Ssos * This can be in the form of a textual message at program startup or
213584Ssos * in documentation (online or textual) provided with the package.
223584Ssos *
233584Ssos * Redistribution and use in source and binary forms, with or without
2483366Sjulian * modification, are permitted provided that the following conditions
2583366Sjulian * are met:
263584Ssos * 1. Redistributions of source code must retain the copyright
273584Ssos *    notice, this list of conditions and the following disclaimer.
2818444Sbde * 2. Redistributions in binary form must reproduce the above copyright
2918444Sbde *    notice, this list of conditions and the following disclaimer in the
303584Ssos *    documentation and/or other materials provided with the distribution.
3118444Sbde * 3. All advertising materials mentioning features or use of this software
323584Ssos *    must display the following acknowledgement:
3311397Sswallace *    "This product includes cryptographic software written by
343584Ssos *     Eric Young (eay@cryptsoft.com)"
3511397Sswallace *    The word 'cryptographic' can be left out if the rouines from the library
3611397Sswallace *    being used are not cryptographic related :-).
3711397Sswallace * 4. If you include any Windows specific code (or a derivative thereof) from
3811397Sswallace *    the apps directory (application code) you must include an acknowledgement:
3911397Sswallace *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4011397Sswallace *
4111397Sswallace * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4211397Sswallace * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4311397Sswallace * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4411397Sswallace * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4511397Sswallace * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4611397Sswallace * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4711397Sswallace * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4811397Sswallace * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4911397Sswallace * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5011397Sswallace * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5111397Sswallace * SUCH DAMAGE.
5211397Sswallace *
5311397Sswallace * The licence and distribution terms for any publically available version or
5411397Sswallace * derivative of this code cannot be changed.  i.e. this code cannot simply be
5511397Sswallace * copied and put under another distribution licence
5611397Sswallace * [including the GNU Public Licence.]
5711397Sswallace */
5811397Sswallace
593584Ssos#include <stdio.h>
6011397Sswallace#include <openssl/bn.h>
6111397Sswallace#include <openssl/dh.h>
6211397Sswallace#include <openssl/err.h>
6311397Sswallace#include <openssl/fips.h>
6411397Sswallace
6511397Sswallace/*-
6611397Sswallace * Check that p is a safe prime and
6711397Sswallace * if g is 2, 3 or 5, check that is is a suitable generator
6811397Sswallace * where
6911397Sswallace * for 2, p mod 24 == 11
7011397Sswallace * for 3, p mod 12 == 5
7111397Sswallace * for 5, p mod 10 == 3 or 7
7211397Sswallace * should hold.
7311397Sswallace */
7411397Sswallace
753584Ssos#ifdef OPENSSL_FIPS
7611397Sswallace
7711397Sswallaceint DH_check(const DH *dh, int *ret)
783584Ssos{
7911397Sswallace    int ok = 0;
8011397Sswallace    BN_CTX *ctx = NULL;
8111397Sswallace    BN_ULONG l;
8211397Sswallace    BIGNUM *q = NULL;
8311397Sswallace
8411397Sswallace    *ret = 0;
8511397Sswallace    ctx = BN_CTX_new();
8611397Sswallace    if (ctx == NULL)
8711397Sswallace        goto err;
8811397Sswallace    q = BN_new();
8911397Sswallace    if (q == NULL)
9011397Sswallace        goto err;
9111397Sswallace
9211397Sswallace    if (BN_is_word(dh->g, DH_GENERATOR_2)) {
9311397Sswallace        l = BN_mod_word(dh->p, 24);
9411397Sswallace        if (l != 11)
9511397Sswallace            *ret |= DH_NOT_SUITABLE_GENERATOR;
9611397Sswallace    }
9711397Sswallace# if 0
9811397Sswallace    else if (BN_is_word(dh->g, DH_GENERATOR_3)) {
9911397Sswallace        l = BN_mod_word(dh->p, 12);
10011397Sswallace        if (l != 5)
10111397Sswallace            *ret |= DH_NOT_SUITABLE_GENERATOR;
10211397Sswallace    }
10311397Sswallace# endif
10411397Sswallace    else if (BN_is_word(dh->g, DH_GENERATOR_5)) {
10511397Sswallace        l = BN_mod_word(dh->p, 10);
10611397Sswallace        if ((l != 3) && (l != 7))
1073584Ssos            *ret |= DH_NOT_SUITABLE_GENERATOR;
10811397Sswallace    } else
10911397Sswallace        *ret |= DH_UNABLE_TO_CHECK_GENERATOR;
1103584Ssos
1113584Ssos    if (!BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL))
11211397Sswallace        *ret |= DH_CHECK_P_NOT_PRIME;
11311397Sswallace    else {
11411397Sswallace        if (!BN_rshift1(q, dh->p))
11511397Sswallace            goto err;
11611397Sswallace        if (!BN_is_prime_ex(q, BN_prime_checks, ctx, NULL))
11711397Sswallace            *ret |= DH_CHECK_P_NOT_SAFE_PRIME;
1183584Ssos    }
1193584Ssos    ok = 1;
12011397Sswallace err:
12111397Sswallace    if (ctx != NULL)
12211397Sswallace        BN_CTX_free(ctx);
12311397Sswallace    if (q != NULL)
1243584Ssos        BN_free(q);
1253584Ssos    return (ok);
12692761Salfred}
1273584Ssos
12818444Sbdeint DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
129{
130    int ok = 0;
131    BIGNUM *q = NULL;
132
133    *ret = 0;
134    q = BN_new();
135    if (q == NULL)
136        goto err;
137    BN_set_word(q, 1);
138    if (BN_cmp(pub_key, q) <= 0)
139        *ret |= DH_CHECK_PUBKEY_TOO_SMALL;
140    BN_copy(q, dh->p);
141    BN_sub_word(q, 1);
142    if (BN_cmp(pub_key, q) >= 0)
143        *ret |= DH_CHECK_PUBKEY_TOO_LARGE;
144
145    ok = 1;
146 err:
147    if (q != NULL)
148        BN_free(q);
149    return (ok);
150}
151
152#endif
153