123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- /*
- * Dropbear - a SSH2 server
- *
- * Copyright (c) 2002,2003 Matt Johnston
- * All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE. */
- #include "includes.h"
- #include "dbutil.h"
- #include "signkey.h"
- #include "bignum.h"
- #include "dbrandom.h"
- #include "buffer.h"
- #include "gendss.h"
- #include "dss.h"
- #define QSIZE 20 /* 160 bit */
- /* This is just a test */
- #if DROPBEAR_DSS
- static void getq(const dropbear_dss_key *key);
- static void getp(const dropbear_dss_key *key, unsigned int size);
- static void getg(const dropbear_dss_key *key);
- static void getx(const dropbear_dss_key *key);
- static void gety(const dropbear_dss_key *key);
- dropbear_dss_key * gen_dss_priv_key(unsigned int size) {
- dropbear_dss_key *key;
- if (size != 1024) {
- dropbear_exit("DSS keys have a fixed size of 1024 bits");
- }
- key = m_malloc(sizeof(*key));
- m_mp_alloc_init_multi(&key->p, &key->q, &key->g, &key->y, &key->x, NULL);
-
- getq(key);
- getp(key, size/8);
- getg(key);
- getx(key);
- gety(key);
- return key;
-
- }
- static void getq(const dropbear_dss_key *key) {
- unsigned char buf[QSIZE];
- int trials;
- /* 160 bit prime */
- genrandom(buf, QSIZE);
- buf[0] |= 0x80; /* top bit high */
- buf[QSIZE-1] |= 0x01; /* bottom bit high */
- bytes_to_mp(key->q, buf, QSIZE);
- /* ask FIPS 186.4 how many Rabin-Miller trials are required */
- trials = mp_prime_rabin_miller_trials(mp_count_bits(key->q));
- if (mp_prime_next_prime(key->q, trials, 0) != MP_OKAY) {
- fprintf(stderr, "DSS key generation failed\n");
- exit(1);
- }
- }
- static void getp(const dropbear_dss_key *key, unsigned int size) {
- DEF_MP_INT(tempX);
- DEF_MP_INT(tempC);
- DEF_MP_INT(tempP);
- DEF_MP_INT(temp2q);
- int result, trials;
- unsigned char *buf;
- m_mp_init_multi(&tempX, &tempC, &tempP, &temp2q, NULL);
- /* 2*q */
- if (mp_mul_d(key->q, 2, &temp2q) != MP_OKAY) {
- fprintf(stderr, "DSS key generation failed\n");
- exit(1);
- }
-
- buf = (unsigned char*)m_malloc(size);
- result = 0;
- do {
-
- genrandom(buf, size);
- buf[0] |= 0x80; /* set the top bit high */
- /* X is a random mp_int */
- bytes_to_mp(&tempX, buf, size);
- /* C = X mod 2q */
- if (mp_mod(&tempX, &temp2q, &tempC) != MP_OKAY) {
- fprintf(stderr, "DSS key generation failed\n");
- exit(1);
- }
- /* P = X - (C - 1) = X - C + 1*/
- if (mp_sub(&tempX, &tempC, &tempP) != MP_OKAY) {
- fprintf(stderr, "DSS key generation failed\n");
- exit(1);
- }
-
- if (mp_add_d(&tempP, 1, key->p) != MP_OKAY) {
- fprintf(stderr, "DSS key generation failed\n");
- exit(1);
- }
- /* ask FIPS 186.4 how many Rabin-Miller trials are required */
- trials = mp_prime_rabin_miller_trials(mp_count_bits(key->p));
- /* result == 1 => p is prime */
- if (mp_prime_is_prime(key->p, trials, &result) != MP_OKAY) {
- fprintf(stderr, "DSS key generation failed\n");
- exit(1);
- }
- } while (!result);
- mp_clear_multi(&tempX, &tempC, &tempP, &temp2q, NULL);
- m_burn(buf, size);
- m_free(buf);
- }
- static void getg(const dropbear_dss_key * key) {
- DEF_MP_INT(div);
- DEF_MP_INT(h);
- DEF_MP_INT(val);
- m_mp_init_multi(&div, &h, &val, NULL);
- /* get div=(p-1)/q */
- if (mp_sub_d(key->p, 1, &val) != MP_OKAY) {
- fprintf(stderr, "DSS key generation failed\n");
- exit(1);
- }
- if (mp_div(&val, key->q, &div, NULL) != MP_OKAY) {
- fprintf(stderr, "DSS key generation failed\n");
- exit(1);
- }
- /* initialise h=1 */
- mp_set(&h, 1);
- do {
- /* now keep going with g=h^div mod p, until g > 1 */
- if (mp_exptmod(&h, &div, key->p, key->g) != MP_OKAY) {
- fprintf(stderr, "DSS key generation failed\n");
- exit(1);
- }
- if (mp_add_d(&h, 1, &h) != MP_OKAY) {
- fprintf(stderr, "DSS key generation failed\n");
- exit(1);
- }
-
- } while (mp_cmp_d(key->g, 1) != MP_GT);
- mp_clear_multi(&div, &h, &val, NULL);
- }
- static void getx(const dropbear_dss_key *key) {
- gen_random_mpint(key->q, key->x);
- }
- static void gety(const dropbear_dss_key *key) {
- if (mp_exptmod(key->g, key->x, key->p, key->y) != MP_OKAY) {
- fprintf(stderr, "DSS key generation failed\n");
- exit(1);
- }
- }
- #endif /* DROPBEAR_DSS */
|