2 * Dropbear - a SSH2 server
4 * Copyright (c) 2002,2003 Matt Johnston
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:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
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
34 #define QSIZE 20 /* 160 bit */
36 /* This is just a test */
40 static void getq(dropbear_dss_key
*key
);
41 static void getp(dropbear_dss_key
*key
, unsigned int size
);
42 static void getg(dropbear_dss_key
*key
);
43 static void getx(dropbear_dss_key
*key
);
44 static void gety(dropbear_dss_key
*key
);
46 dropbear_dss_key
* gen_dss_priv_key(unsigned int size
) {
48 dropbear_dss_key
*key
;
51 dropbear_exit("DSS keys have a fixed size of 1024 bits");
54 key
= m_malloc(sizeof(*key
));
56 m_mp_alloc_init_multi(&key
->p
, &key
->q
, &key
->g
, &key
->y
, &key
->x
, NULL
);
68 static void getq(dropbear_dss_key
*key
) {
73 genrandom(buf
, QSIZE
);
74 buf
[0] |= 0x80; /* top bit high */
75 buf
[QSIZE
-1] |= 0x01; /* bottom bit high */
77 bytes_to_mp(key
->q
, buf
, QSIZE
);
79 /* 18 rounds are required according to HAC */
80 if (mp_prime_next_prime(key
->q
, 18, 0) != MP_OKAY
) {
81 fprintf(stderr
, "DSS key generation failed\n");
86 static void getp(dropbear_dss_key
*key
, unsigned int size
) {
95 m_mp_init_multi(&tempX
, &tempC
, &tempP
, &temp2q
, NULL
);
99 if (mp_mul_d(key
->q
, 2, &temp2q
) != MP_OKAY
) {
100 fprintf(stderr
, "DSS key generation failed\n");
104 buf
= (unsigned char*)m_malloc(size
);
109 genrandom(buf
, size
);
110 buf
[0] |= 0x80; /* set the top bit high */
112 /* X is a random mp_int */
113 bytes_to_mp(&tempX
, buf
, size
);
116 if (mp_mod(&tempX
, &temp2q
, &tempC
) != MP_OKAY
) {
117 fprintf(stderr
, "DSS key generation failed\n");
121 /* P = X - (C - 1) = X - C + 1*/
122 if (mp_sub(&tempX
, &tempC
, &tempP
) != MP_OKAY
) {
123 fprintf(stderr
, "DSS key generation failed\n");
127 if (mp_add_d(&tempP
, 1, key
->p
) != MP_OKAY
) {
128 fprintf(stderr
, "DSS key generation failed\n");
132 /* now check for prime, 5 rounds is enough according to HAC */
133 /* result == 1 => p is prime */
134 if (mp_prime_is_prime(key
->p
, 5, &result
) != MP_OKAY
) {
135 fprintf(stderr
, "DSS key generation failed\n");
140 mp_clear_multi(&tempX
, &tempC
, &tempP
, &temp2q
, NULL
);
145 static void getg(dropbear_dss_key
* key
) {
151 m_mp_init_multi(&div
, &h
, &val
, NULL
);
153 /* get div=(p-1)/q */
154 if (mp_sub_d(key
->p
, 1, &val
) != MP_OKAY
) {
155 fprintf(stderr
, "DSS key generation failed\n");
158 if (mp_div(&val
, key
->q
, &div
, NULL
) != MP_OKAY
) {
159 fprintf(stderr
, "DSS key generation failed\n");
166 /* now keep going with g=h^div mod p, until g > 1 */
167 if (mp_exptmod(&h
, &div
, key
->p
, key
->g
) != MP_OKAY
) {
168 fprintf(stderr
, "DSS key generation failed\n");
172 if (mp_add_d(&h
, 1, &h
) != MP_OKAY
) {
173 fprintf(stderr
, "DSS key generation failed\n");
177 } while (mp_cmp_d(key
->g
, 1) != MP_GT
);
179 mp_clear_multi(&div
, &h
, &val
, NULL
);
182 static void getx(dropbear_dss_key
*key
) {
184 gen_random_mpint(key
->q
, key
->x
);
187 static void gety(dropbear_dss_key
*key
) {
189 if (mp_exptmod(key
->g
, key
->x
, key
->p
, key
->y
) != MP_OKAY
) {
190 fprintf(stderr
, "DSS key generation failed\n");
195 #endif /* DROPBEAR_DSS */