Coverage Report

Created: 2025-08-27 07:03

/src/dropbear/src/gendss.c
Line
Count
Source (jump to first uncovered line)
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 "dbrandom.h"
30
#include "buffer.h"
31
#include "gendss.h"
32
#include "dss.h"
33
34
0
#define QSIZE 20 /* 160 bit */
35
36
/* This is just a test */
37
38
#if DROPBEAR_DSS
39
40
static void getq(const dropbear_dss_key *key);
41
static void getp(const dropbear_dss_key *key, unsigned int size);
42
static void getg(const dropbear_dss_key *key);
43
static void getx(const dropbear_dss_key *key);
44
static void gety(const dropbear_dss_key *key);
45
46
0
dropbear_dss_key * gen_dss_priv_key(unsigned int size) {
47
48
0
  dropbear_dss_key *key;
49
50
0
  if (size != 1024) {
51
0
    dropbear_exit("DSS keys have a fixed size of 1024 bits");
52
0
  }
53
54
0
  key = m_malloc(sizeof(*key));
55
56
0
  m_mp_alloc_init_multi(&key->p, &key->q, &key->g, &key->y, &key->x, NULL);
57
  
58
0
  getq(key);
59
0
  getp(key, size/8);
60
0
  getg(key);
61
0
  getx(key);
62
0
  gety(key);
63
64
0
  return key;
65
  
66
0
}
67
68
0
static void getq(const dropbear_dss_key *key) {
69
70
0
  unsigned char buf[QSIZE];
71
0
  int trials;
72
73
  /* 160 bit prime */
74
0
  genrandom(buf, QSIZE);
75
0
  buf[0] |= 0x80; /* top bit high */
76
0
  buf[QSIZE-1] |= 0x01; /* bottom bit high */
77
78
0
  bytes_to_mp(key->q, buf, QSIZE);
79
80
  /* ask FIPS 186.4 how many Rabin-Miller trials are required */
81
0
  trials = mp_prime_rabin_miller_trials(mp_count_bits(key->q));
82
0
  if (mp_prime_next_prime(key->q, trials, 0) != MP_OKAY) {
83
0
    fprintf(stderr, "DSS key generation failed\n");
84
0
    exit(1);
85
0
  }
86
0
}
87
88
0
static void getp(const dropbear_dss_key *key, unsigned int size) {
89
90
0
  DEF_MP_INT(tempX);
91
0
  DEF_MP_INT(tempC);
92
0
  DEF_MP_INT(tempP);
93
0
  DEF_MP_INT(temp2q);
94
0
  int result, trials;
95
0
  unsigned char *buf;
96
97
0
  m_mp_init_multi(&tempX, &tempC, &tempP, &temp2q, NULL);
98
99
100
  /* 2*q */
101
0
  if (mp_mul_d(key->q, 2, &temp2q) != MP_OKAY) {
102
0
    fprintf(stderr, "DSS key generation failed\n");
103
0
    exit(1);
104
0
  }
105
  
106
0
  buf = (unsigned char*)m_malloc(size);
107
108
0
  result = 0;
109
0
  do {
110
    
111
0
    genrandom(buf, size);
112
0
    buf[0] |= 0x80; /* set the top bit high */
113
114
    /* X is a random mp_int */
115
0
    bytes_to_mp(&tempX, buf, size);
116
117
    /* C = X mod 2q */
118
0
    if (mp_mod(&tempX, &temp2q, &tempC) != MP_OKAY) {
119
0
      fprintf(stderr, "DSS key generation failed\n");
120
0
      exit(1);
121
0
    }
122
123
    /* P = X - (C - 1) = X - C + 1*/
124
0
    if (mp_sub(&tempX, &tempC, &tempP) != MP_OKAY) {
125
0
      fprintf(stderr, "DSS key generation failed\n");
126
0
      exit(1);
127
0
    }
128
    
129
0
    if (mp_add_d(&tempP, 1, key->p) != MP_OKAY) {
130
0
      fprintf(stderr, "DSS key generation failed\n");
131
0
      exit(1);
132
0
    }
133
134
    /* ask FIPS 186.4 how many Rabin-Miller trials are required */
135
0
    trials = mp_prime_rabin_miller_trials(mp_count_bits(key->p));
136
    /* result == 1  =>  p is prime */
137
0
    if (mp_prime_is_prime(key->p, trials, &result) != MP_OKAY) {
138
0
      fprintf(stderr, "DSS key generation failed\n");
139
0
      exit(1);
140
0
    }
141
0
  } while (!result);
142
143
0
  mp_clear_multi(&tempX, &tempC, &tempP, &temp2q, NULL);
144
0
  m_burn(buf, size);
145
0
  m_free(buf);
146
0
}
147
148
0
static void getg(const dropbear_dss_key * key) {
149
150
0
  DEF_MP_INT(div);
151
0
  DEF_MP_INT(h);
152
0
  DEF_MP_INT(val);
153
154
0
  m_mp_init_multi(&div, &h, &val, NULL);
155
156
  /* get div=(p-1)/q */
157
0
  if (mp_sub_d(key->p, 1, &val) != MP_OKAY) {
158
0
    fprintf(stderr, "DSS key generation failed\n");
159
0
    exit(1);
160
0
  }
161
0
  if (mp_div(&val, key->q, &div, NULL) != MP_OKAY) {
162
0
    fprintf(stderr, "DSS key generation failed\n");
163
0
    exit(1);
164
0
  }
165
166
  /* initialise h=1 */
167
0
  mp_set(&h, 1);
168
0
  do {
169
    /* now keep going with g=h^div mod p, until g > 1 */
170
0
    if (mp_exptmod(&h, &div, key->p, key->g) != MP_OKAY) {
171
0
      fprintf(stderr, "DSS key generation failed\n");
172
0
      exit(1);
173
0
    }
174
175
0
    if (mp_add_d(&h, 1, &h) != MP_OKAY) {
176
0
      fprintf(stderr, "DSS key generation failed\n");
177
0
      exit(1);
178
0
    }
179
  
180
0
  } while (mp_cmp_d(key->g, 1) != MP_GT);
181
182
0
  mp_clear_multi(&div, &h, &val, NULL);
183
0
}
184
185
0
static void getx(const dropbear_dss_key *key) {
186
187
0
  gen_random_mpint(key->q, key->x);
188
0
}
189
190
0
static void gety(const dropbear_dss_key *key) {
191
192
0
  if (mp_exptmod(key->g, key->x, key->p, key->y) != MP_OKAY) {
193
0
    fprintf(stderr, "DSS key generation failed\n");
194
0
    exit(1);
195
0
  }
196
0
}
197
198
#endif /* DROPBEAR_DSS */