blob: 6b4f6ac3401253bd1c4b4fb770b34b74e0eab02f [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * Diffie-Hellman-Merkle key exchange (prime generation)
3 *
Paul Bakker530927b2015-02-13 14:24:10 +01004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
Manuel Pégourié-Gonnarde12abf92015-01-28 17:13:45 +00006 * This file is part of mbed TLS (https://polarssl.org)
Paul Bakkere0ccd0a2009-01-04 16:27:10 +00007 *
Paul Bakker5121ce52009-01-03 21:22:43 +00008 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23#ifndef _CRT_SECURE_NO_DEPRECATE
24#define _CRT_SECURE_NO_DEPRECATE 1
25#endif
26
27#include <stdio.h>
Manuel Pégourié-Gonnardf3331742015-07-03 17:18:10 +020028#include <stdlib.h>
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Paul Bakker40e46942009-01-03 21:51:57 +000030#include "polarssl/config.h"
Paul Bakker5690efc2011-05-26 13:16:06 +000031
32#include "polarssl/bignum.h"
Paul Bakker508ad5a2011-12-04 17:09:26 +000033#include "polarssl/entropy.h"
34#include "polarssl/ctr_drbg.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000035
Manuel Pégourié-Gonnardf3331742015-07-03 17:18:10 +020036#define USAGE \
37 "\n usage: dh_genprime param=<>...\n" \
38 "\n acceprable parameters:\n" \
39 " bits=%%d default: 2048\n"
40
41#define DFL_BITS 2048
42
Paul Bakker5121ce52009-01-03 21:22:43 +000043/*
44 * Note: G = 4 is always a quadratic residue mod P,
45 * so it is a generator of order Q (with P = 2*Q+1).
46 */
Paul Bakker5121ce52009-01-03 21:22:43 +000047#define GENERATOR "4"
48
Paul Bakker508ad5a2011-12-04 17:09:26 +000049#if !defined(POLARSSL_BIGNUM_C) || !defined(POLARSSL_ENTROPY_C) || \
50 !defined(POLARSSL_FS_IO) || !defined(POLARSSL_CTR_DRBG_C)
Paul Bakkercce9d772011-11-18 14:26:47 +000051int main( int argc, char *argv[] )
Paul Bakker5690efc2011-05-26 13:16:06 +000052{
Paul Bakkercce9d772011-11-18 14:26:47 +000053 ((void) argc);
54 ((void) argv);
55
Paul Bakker508ad5a2011-12-04 17:09:26 +000056 printf("POLARSSL_BIGNUM_C and/or POLARSSL_ENTROPY_C and/or "
57 "POLARSSL_FS_IO and/or POLARSSL_CTR_DRBG_C not defined.\n");
Paul Bakker5690efc2011-05-26 13:16:06 +000058 return( 0 );
59}
60#else
Paul Bakkercce9d772011-11-18 14:26:47 +000061int main( int argc, char *argv[] )
Paul Bakker5121ce52009-01-03 21:22:43 +000062{
63 int ret = 1;
64
Paul Bakker40e46942009-01-03 21:51:57 +000065#if defined(POLARSSL_GENPRIME)
Paul Bakker5121ce52009-01-03 21:22:43 +000066 mpi G, P, Q;
Paul Bakker508ad5a2011-12-04 17:09:26 +000067 entropy_context entropy;
68 ctr_drbg_context ctr_drbg;
Paul Bakkere0225e42013-06-06 12:52:24 +020069 const char *pers = "dh_genprime";
Paul Bakker5121ce52009-01-03 21:22:43 +000070 FILE *fout;
Manuel Pégourié-Gonnardf3331742015-07-03 17:18:10 +020071 int nbits = DFL_BITS;
72 int i;
73 char *p, *q;
Paul Bakkercce9d772011-11-18 14:26:47 +000074
Paul Bakker6c591fa2011-05-05 11:49:20 +000075 mpi_init( &G ); mpi_init( &P ); mpi_init( &Q );
Paul Bakker39148402014-04-17 16:02:36 +020076 entropy_init( &entropy );
Paul Bakker993f02c2014-04-17 16:00:59 +020077
Manuel Pégourié-Gonnardf3331742015-07-03 17:18:10 +020078 if( argc == 0 )
79 {
80 usage:
81 printf( USAGE );
82 return( 1 );
83 }
84
85 for( i = 1; i < argc; i++ )
86 {
87 p = argv[i];
88 if( ( q = strchr( p, '=' ) ) == NULL )
89 goto usage;
90 *q++ = '\0';
91
92 if( strcmp( p, "bits" ) == 0 )
93 {
94 nbits = atoi( q );
95 if( nbits < 0 || nbits > POLARSSL_MPI_MAX_BITS )
96 goto usage;
97 }
98 else
99 goto usage;
100 }
101
Paul Bakker993f02c2014-04-17 16:00:59 +0200102 if( ( ret = mpi_read_string( &G, 10, GENERATOR ) ) != 0 )
103 {
104 printf( " failed\n ! mpi_read_string returned %d\n", ret );
105 goto exit;
106 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000107
108 printf( "\n . Seeding the random number generator..." );
109 fflush( stdout );
110
Paul Bakker508ad5a2011-12-04 17:09:26 +0000111 if( ( ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy,
Paul Bakkere0225e42013-06-06 12:52:24 +0200112 (const unsigned char *) pers,
113 strlen( pers ) ) ) != 0 )
Paul Bakker508ad5a2011-12-04 17:09:26 +0000114 {
115 printf( " failed\n ! ctr_drbg_init returned %d\n", ret );
116 goto exit;
117 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000118
119 printf( " ok\n . Generating the modulus, please wait..." );
120 fflush( stdout );
121
122 /*
123 * This can take a long time...
124 */
Manuel Pégourié-Gonnardf3331742015-07-03 17:18:10 +0200125 if( ( ret = mpi_gen_prime( &P, nbits, 1,
Paul Bakker508ad5a2011-12-04 17:09:26 +0000126 ctr_drbg_random, &ctr_drbg ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000127 {
128 printf( " failed\n ! mpi_gen_prime returned %d\n\n", ret );
129 goto exit;
130 }
131
132 printf( " ok\n . Verifying that Q = (P-1)/2 is prime..." );
133 fflush( stdout );
134
135 if( ( ret = mpi_sub_int( &Q, &P, 1 ) ) != 0 )
136 {
137 printf( " failed\n ! mpi_sub_int returned %d\n\n", ret );
138 goto exit;
139 }
140
141 if( ( ret = mpi_div_int( &Q, NULL, &Q, 2 ) ) != 0 )
142 {
143 printf( " failed\n ! mpi_div_int returned %d\n\n", ret );
144 goto exit;
145 }
146
Paul Bakker508ad5a2011-12-04 17:09:26 +0000147 if( ( ret = mpi_is_prime( &Q, ctr_drbg_random, &ctr_drbg ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000148 {
149 printf( " failed\n ! mpi_is_prime returned %d\n\n", ret );
150 goto exit;
151 }
152
153 printf( " ok\n . Exporting the value in dh_prime.txt..." );
154 fflush( stdout );
155
156 if( ( fout = fopen( "dh_prime.txt", "wb+" ) ) == NULL )
157 {
158 ret = 1;
159 printf( " failed\n ! Could not create dh_prime.txt\n\n" );
160 goto exit;
161 }
162
163 if( ( ret = mpi_write_file( "P = ", &P, 16, fout ) != 0 ) ||
164 ( ret = mpi_write_file( "G = ", &G, 16, fout ) != 0 ) )
165 {
166 printf( " failed\n ! mpi_write_file returned %d\n\n", ret );
167 goto exit;
168 }
169
170 printf( " ok\n\n" );
171 fclose( fout );
172
173exit:
174
Paul Bakker6c591fa2011-05-05 11:49:20 +0000175 mpi_free( &G ); mpi_free( &P ); mpi_free( &Q );
Paul Bakker5121ce52009-01-03 21:22:43 +0000176#else
177 printf( "\n ! Prime-number generation is not available.\n\n" );
178#endif
179
Paul Bakkercce9d772011-11-18 14:26:47 +0000180#if defined(_WIN32)
Paul Bakker5121ce52009-01-03 21:22:43 +0000181 printf( " Press Enter to exit this program.\n" );
182 fflush( stdout ); getchar();
183#endif
184
185 return( ret );
186}
Paul Bakker508ad5a2011-12-04 17:09:26 +0000187#endif /* POLARSSL_BIGNUM_C && POLARSSL_ENTROPY_C && POLARSSL_FS_IO &&
188 POLARSSL_CTR_DRBG_C */