• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Dropbear - a SSH2 server
3  *
4  * Copyright (c) 2002,2003 Matt Johnston
5  * All rights reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE. */
24 
25 #include "includes.h"
26 #include "dbutil.h"
27 #include "signkey.h"
28 #include "bignum.h"
29 #include "random.h"
30 #include "buffer.h"
31 #include "gendss.h"
32 #include "dss.h"
33 
34 #define QSIZE 20 /* 160 bit */
35 
36 /* This is just a test */
37 
38 #ifdef DROPBEAR_DSS
39 
40 static void getq(dss_key *key);
41 static void getp(dss_key *key, unsigned int size);
42 static void getg(dss_key *key);
43 static void getx(dss_key *key);
44 static void gety(dss_key *key);
45 
gen_dss_priv_key(unsigned int size)46 dss_key * gen_dss_priv_key(unsigned int size) {
47 
48 	dss_key *key;
49 
50 	key = (dss_key*)m_malloc(sizeof(dss_key));
51 
52 	key->p = (mp_int*)m_malloc(sizeof(mp_int));
53 	key->q = (mp_int*)m_malloc(sizeof(mp_int));
54 	key->g = (mp_int*)m_malloc(sizeof(mp_int));
55 	key->y = (mp_int*)m_malloc(sizeof(mp_int));
56 	key->x = (mp_int*)m_malloc(sizeof(mp_int));
57 	m_mp_init_multi(key->p, key->q, key->g, key->y, key->x, NULL);
58 
59 	seedrandom();
60 
61 	getq(key);
62 	getp(key, size);
63 	getg(key);
64 	getx(key);
65 	gety(key);
66 
67 	return key;
68 
69 }
70 
getq(dss_key * key)71 static void getq(dss_key *key) {
72 
73 	char buf[QSIZE];
74 
75 	/* 160 bit prime */
76 	genrandom(buf, QSIZE);
77 	buf[0] |= 0x80; /* top bit high */
78 	buf[QSIZE-1] |= 0x01; /* bottom bit high */
79 
80 	bytes_to_mp(key->q, buf, QSIZE);
81 
82 	/* 18 rounds are required according to HAC */
83 	if (mp_prime_next_prime(key->q, 18, 0) != MP_OKAY) {
84 		fprintf(stderr, "dss key generation failed\n");
85 		exit(1);
86 	}
87 }
88 
getp(dss_key * key,unsigned int size)89 static void getp(dss_key *key, unsigned int size) {
90 
91 	DEF_MP_INT(tempX);
92 	DEF_MP_INT(tempC);
93 	DEF_MP_INT(tempP);
94 	DEF_MP_INT(temp2q);
95 	int result;
96 	unsigned char *buf;
97 
98 	m_mp_init_multi(&tempX, &tempC, &tempP, &temp2q, NULL);
99 
100 
101 	/* 2*q */
102 	if (mp_mul_d(key->q, 2, &temp2q) != MP_OKAY) {
103 		fprintf(stderr, "dss key generation failed\n");
104 		exit(1);
105 	}
106 
107 	buf = (unsigned char*)m_malloc(size);
108 
109 	result = 0;
110 	do {
111 
112 		genrandom(buf, size);
113 		buf[0] |= 0x80; /* set the top bit high */
114 
115 		/* X is a random mp_int */
116 		bytes_to_mp(&tempX, buf, size);
117 
118 		/* C = X mod 2q */
119 		if (mp_mod(&tempX, &temp2q, &tempC) != MP_OKAY) {
120 			fprintf(stderr, "dss key generation failed\n");
121 			exit(1);
122 		}
123 
124 		/* P = X - (C - 1) = X - C + 1*/
125 		if (mp_sub(&tempX, &tempC, &tempP) != MP_OKAY) {
126 			fprintf(stderr, "dss key generation failed\n");
127 			exit(1);
128 		}
129 
130 		if (mp_add_d(&tempP, 1, key->p) != MP_OKAY) {
131 			fprintf(stderr, "dss key generation failed\n");
132 			exit(1);
133 		}
134 
135 		/* now check for prime, 5 rounds is enough according to HAC */
136 		/* result == 1  =>  p is prime */
137 		if (mp_prime_is_prime(key->p, 5, &result) != MP_OKAY) {
138 			fprintf(stderr, "dss key generation failed\n");
139 			exit(1);
140 		}
141 	} while (!result);
142 
143 	mp_clear_multi(&tempX, &tempC, &tempP, &temp2q, NULL);
144 	m_burn(buf, size);
145 	m_free(buf);
146 }
147 
getg(dss_key * key)148 static void getg(dss_key * key) {
149 
150 	DEF_MP_INT(div);
151 	DEF_MP_INT(h);
152 	DEF_MP_INT(val);
153 
154 	m_mp_init_multi(&div, &h, &val, NULL);
155 
156 	/* get div=(p-1)/q */
157 	if (mp_sub_d(key->p, 1, &val) != MP_OKAY) {
158 		fprintf(stderr, "dss key generation failed\n");
159 		exit(1);
160 	}
161 	if (mp_div(&val, key->q, &div, NULL) != MP_OKAY) {
162 		fprintf(stderr, "dss key generation failed\n");
163 		exit(1);
164 	}
165 
166 	/* initialise h=1 */
167 	mp_set(&h, 1);
168 	do {
169 		/* now keep going with g=h^div mod p, until g > 1 */
170 		if (mp_exptmod(&h, &div, key->p, key->g) != MP_OKAY) {
171 			fprintf(stderr, "dss key generation failed\n");
172 			exit(1);
173 		}
174 
175 		if (mp_add_d(&h, 1, &h) != MP_OKAY) {
176 			fprintf(stderr, "dss key generation failed\n");
177 			exit(1);
178 		}
179 
180 	} while (mp_cmp_d(key->g, 1) != MP_GT);
181 
182 	mp_clear_multi(&div, &h, &val, NULL);
183 }
184 
getx(dss_key * key)185 static void getx(dss_key *key) {
186 
187 	gen_random_mpint(key->q, key->x);
188 }
189 
gety(dss_key * key)190 static void gety(dss_key *key) {
191 
192 	if (mp_exptmod(key->g, key->x, key->p, key->y) != MP_OKAY) {
193 		fprintf(stderr, "dss key generation failed\n");
194 		exit(1);
195 	}
196 }
197 
198 #endif /* DROPBEAR_DSS */
199