Home | History | Annotate | Download | only in dropbear
      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 
     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 
     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 
     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 
    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 
    185 static void getx(dss_key *key) {
    186 
    187 	gen_random_mpint(key->q, key->x);
    188 }
    189 
    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