155714Skris/* crypto/dh/dhtest.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
855714Skris *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1555714Skris *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
2255714Skris *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
3755714Skris * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4055714Skris *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
5255714Skris *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
59160814Ssimon/* Until the key-gen callbacks are modified to use newer prototypes, we allow
60160814Ssimon * deprecated functions for openssl-internal code */
61160814Ssimon#ifdef OPENSSL_NO_DEPRECATED
62160814Ssimon#undef OPENSSL_NO_DEPRECATED
63160814Ssimon#endif
64160814Ssimon
6555714Skris#include <stdio.h>
6655714Skris#include <stdlib.h>
6755714Skris#include <string.h>
68109998Smarkm
69109998Smarkm#include "../e_os.h"
70109998Smarkm
7155714Skris#include <openssl/crypto.h>
7255714Skris#include <openssl/bio.h>
7355714Skris#include <openssl/bn.h>
7459191Skris#include <openssl/rand.h>
75100928Snectar#include <openssl/err.h>
7655714Skris
77109998Smarkm#ifdef OPENSSL_NO_DH
7855714Skrisint main(int argc, char *argv[])
7955714Skris{
8055714Skris    printf("No DH support\n");
8155714Skris    return(0);
8255714Skris}
8355714Skris#else
8455714Skris#include <openssl/dh.h>
8555714Skris
86109998Smarkm#ifdef OPENSSL_SYS_WIN16
8755714Skris#define MS_CALLBACK	_far _loadds
8855714Skris#else
8955714Skris#define MS_CALLBACK
9055714Skris#endif
9155714Skris
92160814Ssimonstatic int MS_CALLBACK cb(int p, int n, BN_GENCB *arg);
9355714Skris
9459191Skrisstatic const char rnd_seed[] = "string to make the random number generator think it has entropy";
9555714Skris
9655714Skrisint main(int argc, char *argv[])
9755714Skris	{
98160814Ssimon	BN_GENCB _cb;
9959191Skris	DH *a;
10059191Skris	DH *b=NULL;
10155714Skris	char buf[12];
10255714Skris	unsigned char *abuf=NULL,*bbuf=NULL;
10355714Skris	int i,alen,blen,aout,bout,ret=1;
10459191Skris	BIO *out;
10555714Skris
106109998Smarkm	CRYPTO_malloc_debug_init();
107109998Smarkm	CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
108109998Smarkm	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
109109998Smarkm
110109998Smarkm#ifdef OPENSSL_SYS_WIN32
11155714Skris	CRYPTO_malloc_init();
11255714Skris#endif
11355714Skris
11459191Skris	RAND_seed(rnd_seed, sizeof rnd_seed);
11559191Skris
11655714Skris	out=BIO_new(BIO_s_file());
117109998Smarkm	if (out == NULL) EXIT(1);
11855714Skris	BIO_set_fp(out,stdout,BIO_NOCLOSE);
11955714Skris
120160814Ssimon	BN_GENCB_set(&_cb, &cb, out);
121160814Ssimon	if(((a = DH_new()) == NULL) || !DH_generate_parameters_ex(a, 64,
122160814Ssimon				DH_GENERATOR_5, &_cb))
123160814Ssimon		goto err;
12455714Skris
125100928Snectar	if (!DH_check(a, &i)) goto err;
126100928Snectar	if (i & DH_CHECK_P_NOT_PRIME)
127100928Snectar		BIO_puts(out, "p value is not prime\n");
128100928Snectar	if (i & DH_CHECK_P_NOT_SAFE_PRIME)
129100928Snectar		BIO_puts(out, "p value is not a safe prime\n");
130100928Snectar	if (i & DH_UNABLE_TO_CHECK_GENERATOR)
131100928Snectar		BIO_puts(out, "unable to check the generator value\n");
132100928Snectar	if (i & DH_NOT_SUITABLE_GENERATOR)
133100928Snectar		BIO_puts(out, "the g value is not a generator\n");
134100928Snectar
13555714Skris	BIO_puts(out,"\np    =");
13655714Skris	BN_print(out,a->p);
13755714Skris	BIO_puts(out,"\ng    =");
13855714Skris	BN_print(out,a->g);
13955714Skris	BIO_puts(out,"\n");
14055714Skris
14155714Skris	b=DH_new();
14255714Skris	if (b == NULL) goto err;
14355714Skris
14455714Skris	b->p=BN_dup(a->p);
14555714Skris	b->g=BN_dup(a->g);
14655714Skris	if ((b->p == NULL) || (b->g == NULL)) goto err;
14755714Skris
148160814Ssimon	/* Set a to run with normal modexp and b to use constant time */
149160814Ssimon	a->flags &= ~DH_FLAG_NO_EXP_CONSTTIME;
150160814Ssimon	b->flags |= DH_FLAG_NO_EXP_CONSTTIME;
151160814Ssimon
15255714Skris	if (!DH_generate_key(a)) goto err;
15355714Skris	BIO_puts(out,"pri 1=");
15455714Skris	BN_print(out,a->priv_key);
15555714Skris	BIO_puts(out,"\npub 1=");
15655714Skris	BN_print(out,a->pub_key);
15755714Skris	BIO_puts(out,"\n");
15855714Skris
15955714Skris	if (!DH_generate_key(b)) goto err;
16055714Skris	BIO_puts(out,"pri 2=");
16155714Skris	BN_print(out,b->priv_key);
16255714Skris	BIO_puts(out,"\npub 2=");
16355714Skris	BN_print(out,b->pub_key);
16455714Skris	BIO_puts(out,"\n");
16555714Skris
16655714Skris	alen=DH_size(a);
16768651Skris	abuf=(unsigned char *)OPENSSL_malloc(alen);
16855714Skris	aout=DH_compute_key(abuf,b->pub_key,a);
16955714Skris
17055714Skris	BIO_puts(out,"key1 =");
17155714Skris	for (i=0; i<aout; i++)
17255714Skris		{
17355714Skris		sprintf(buf,"%02X",abuf[i]);
17455714Skris		BIO_puts(out,buf);
17555714Skris		}
17655714Skris	BIO_puts(out,"\n");
17755714Skris
17855714Skris	blen=DH_size(b);
17968651Skris	bbuf=(unsigned char *)OPENSSL_malloc(blen);
18055714Skris	bout=DH_compute_key(bbuf,a->pub_key,b);
18155714Skris
18255714Skris	BIO_puts(out,"key2 =");
18355714Skris	for (i=0; i<bout; i++)
18455714Skris		{
18555714Skris		sprintf(buf,"%02X",bbuf[i]);
18655714Skris		BIO_puts(out,buf);
18755714Skris		}
18855714Skris	BIO_puts(out,"\n");
18955714Skris	if ((aout < 4) || (bout != aout) || (memcmp(abuf,bbuf,aout) != 0))
19055714Skris		{
19155714Skris		fprintf(stderr,"Error in DH routines\n");
19255714Skris		ret=1;
19355714Skris		}
19455714Skris	else
19555714Skris		ret=0;
19655714Skriserr:
197100928Snectar	ERR_print_errors_fp(stderr);
198100928Snectar
19968651Skris	if (abuf != NULL) OPENSSL_free(abuf);
20068651Skris	if (bbuf != NULL) OPENSSL_free(bbuf);
20159191Skris	if(b != NULL) DH_free(b);
20259191Skris	if(a != NULL) DH_free(a);
20359191Skris	BIO_free(out);
204160814Ssimon#ifdef OPENSSL_SYS_NETWARE
205160814Ssimon    if (ret) printf("ERROR: %d\n", ret);
206160814Ssimon#endif
207109998Smarkm	EXIT(ret);
20855714Skris	return(ret);
20955714Skris	}
21055714Skris
211160814Ssimonstatic int MS_CALLBACK cb(int p, int n, BN_GENCB *arg)
21255714Skris	{
21355714Skris	char c='*';
21455714Skris
21555714Skris	if (p == 0) c='.';
21655714Skris	if (p == 1) c='+';
21755714Skris	if (p == 2) c='*';
21855714Skris	if (p == 3) c='\n';
219160814Ssimon	BIO_write(arg->arg,&c,1);
220160814Ssimon	(void)BIO_flush(arg->arg);
22155714Skris#ifdef LINT
22255714Skris	p=n;
22355714Skris#endif
224160814Ssimon	return 1;
22555714Skris	}
22655714Skris#endif
227